Fastest? We need benchmarks to show that. I can see this being slower than traditional approaches on systems with slow memory, tiny CPU caches, and compilers that don’t do constant string folding.
You can also replace the array by a single string. That may or may not be faster, depending on CPU and language implementation. I think it likely is (rationale: the code writing the array to stdout either does multiple write calls, or builds up the string in memory and then does what the code writing the string does. The code writing the array need not load the string, but it needs to store the array, and that won’t be much smaller, even when it shares strings)
It would be more elegant in a lazy language, but it is probably quite fast since it doesn't need any division (?? My assumption here might be wrong). I typed this out on my phone, so it might not work, and racket isn't my daily driver.
Edit: My initial assumption was correct, but the in-cycle sequence creator has a very large overhead. The final solution for racket (Ugly, because mlist doesn't have any nice things included): https://pastebin.com/aB2BLY1U
The mutable list solution (as one would write it in scheme) is more than twice as fast as the remainder one, and I expect it to be for other languages as well.
I've been looking for an example that shows how pattern matching can make code much both compact and readable. I think this does nicely. Here's an example in Scala:
(1 to 100).map(i => (i % 3, i % 5) match {
case (0, 0) => "FizzBuzz"
case (0, _) => "Fizz"
case (_, 0) => "Buzz"
case _ => s"$i"
}).foreach(println)
Compare that to the rest of the examples on the page. The only one that comes close in either readability or compactness (in my opinion) is the Rust example, mainly because it's syntactically almost identical, just a bit more verbose. I'm really excited that C# 8 will support similar syntax with _ discards.
Well, yes, you're right – like beauty, readability is in the eye of the beholder. I've been writing a ton of Scala code lately, and my version is very Scala-like, so it looks better to me.
That said, I think there are several advantages:
• It's more compact, with fewer lines and fewer characters, but at least as readable
• There's simple separation of concerns: it only has a single print statement – the whole range is transformed, then printed – which makes it easy to refactor later if I need to use those values for something other than printing
• It's obvious that all of the cases are handled
• In an amazing coincidence, it looks like code I write :) so I personally prefer it
If you're implying that there are times that if/elif/else syntax is more readable than pattern matching, then yes, absolutely! There are times when one is preferable, and times when the other is.
Pattern matching is especially nice when you need to include conditionals and types:
vehicle match {
case car: Car if (car.passengers > 2) => addToHovLane(car)
case truck: Truck => reject("No trucks allowed")
case _ => totalTraffic += 1
}
There's a lot of casting going on there, and it's all handled in the pattern match. Converting this to if/else statements would require a lot of type tests and intermediate variables. Personally, I think that would make things harder to read.
That said, sometimes (often!) the more compact code is, the harder it is to read. I think it's always worth taking a few extra characters to improver readability. So I only use pattern matching with types and discards when I think it makes the code more readable and more flexible (e.g. easier to refactor, improves separation of concerns).
BTW, thanks for pushing back on this. I'm working on the 4th edition of Head First C# (O'Reilly), and C# added syntax very similar to this (borrowed from F#). Writing this reply gave me the opportunity to start thinking through how I want to teach it.
Pattern matching seems like a useful technique. The languages I use most often don't have it, so I haven't used it much personally. I can see how it would be nice to have for your vehicle example and things like that. FizzBuzz is just so trivial that I don't think the benefits really shine through as benefits and seem more like just alternate syntax.
Well for one, the cases of a match statement are guaranteed to use the same variables and return the same output, in every case — the equivalent if-elseif-else does not offer the same guarantees, and has to be read in full to reach the same conclusion
So the statements are equivalent in whole, but the difference is that a match statement requires less reading (as it holds more meaning)
I agree with you. Pattern matching is detrimental to readability in this case. Everybody can understand your example above. The pattern matching one leaves me a little O_o (pun intended) despite I'm using pattern matching everyday in Elixir.
I think that’s more a matter of familiarity than of readability proper. The same argument could have been made against Arabic numerals, against the use of “=“ for assignment and “==“ for equality (“=“ had been used in mathematics for equality for ¿centuries?), etc.
One could also argue that, by using the knowledge that “is divisible by 3 and 5” is equivalent to “is divisible by 15”, the code using %15 is cleverer than the example that just follows the problem description.
The Haskell example is quite similar to the Scala/Rust example as well. I guess you could rewrite the Haskell version to match your Scala version pretty closely as well if you prefer doing the tuple construction and then matching on the tuple, like in your Scala version, instead of doing it directly inside the pattern match.
Something like this, with the caveat that I haven't done any proper coding in Haskell in years and I don't have an interpreter installed to verify correctness.
The step in the composition chain breaking down the integers into ordered pairs of the remainders is classy. Well done. For added points we now need an ADT to represent the different possible results of the computation :)
Midnight takes your heart and your soul
While your heart is as high as your soul
Put your heart without your soul into your heart
Give back your heart
Desire is a lovestruck ladykiller
My world is nothing
Fire is ice
Hate is water
Until my world is Desire,
Build my world up
If Midnight taking my world, Fire is nothing and Midnight taking my world, Hate is nothing
Shout "FizzBuzz!"
Take it to the top
If Midnight taking my world, Fire is nothing
Shout "Fizz!"
Take it to the top
If Midnight taking my world, Hate is nothing
Say "Buzz!"
Take it to the top
Whisper my world
The "Haskell implementation using monoids" on this page is the only solution I've seen where adding a new behavior (e.g. "FizzBuzzWoof") only requires a modification in one spot.
(d 3 "Fizz" <> d 5 "Buzz")
becomes
(d 3 "Fizz" <> d 5 "Buzz" <> d 13 "Woof")
eta: And just below it is a similar solution in Python. Cool!
Extra points for deviousness, but this won't produce the correct visual result when logged in on a hardcopy terminal (e.g. DECwriter); or even on a glass tty (e.g. DEC VT100) if you set the upper limit to 10001. It will also always fail a correctness test of diffing against the proper output. You should definitely consider entering the Obfuscated C contest, though.
The Prolog version is fine, but the nested conditionals make it harder to read and may cause confusion about scope (for example, it's not necessary to enclose "divBy3(X),divBy5(X)" in parentheses, as on line 6 in the article).
Here's an alternative version, that avoids nested conditionals and also doesn't use the cut ("!") to control backtracking:
fizzbuzz(X,'Fizz'):-
0 is mod(X,3).
fizzbuzz(X,'Buzz'):-
0 is mod(X,5).
fizzbuzz(X,X):-
\+ fizzbuzz(X,'Fizz')
,\+ fizzbuzz(X,'Buzz').
print_fizzbuzz(N,M):-
N > M.
print_fizzbuzz(N,M):-
N =< M
,forall(fizzbuzz(N,FBN)
,write(FBN)
)
,nl
,succ(N,N_)
,print_fizzbuzz(N_,M).
This one uses Prolog's nondeterminsm to generate either Fizz, Buzz, both, or neither as apropriate and collects them all with forall/2 (yes, Prolog does have for-loops; of a sort), then adds a newline to the output.
The functional why was as a filter for eliminating impostors. At the time it was new, no one could look up the answers for it, because it was such an arbitrary problem. Now, it's just a curiosity.
I wonder how widespread it's become in shitty prepare-for-coding-interview materials, so variations might be needed, but as a tool for identifying non-programmers, it is extremely good. It's ridiculous how good it is, it really shouldn't be, because as a decent programmer, it's so hard to understand how anyone could apply for a programming job, yet still be so bad at programming that they can't pass the test.
And yet, there are so many people like that it's fucking scary.
- fibonacci sequence to n (ooh, look, isn't recursion pretty)
- parallel map (simple demonstration of parallelism in languages that allow it)
[slightly more involved, webapp hello worlds]
- basic blog (various MVC web frameworks, normally along lines of if I run commands x, y and z I get models, views and controllers and it all works)
- basic todo application (various frontend frameworks)
- basic chat application (as a realtime demonstration, generally for websockets)
One common one when learning recursion or lispy things is factorial with recursion? But it's also in proof as well. It may just be really simple or something so I'm not sure my example counts
The whole point of fizzbuzz is to filter for people that can just solve a tiny problem in a reasonably short time-- that's it. Most interviewers will even give some slack if the person has to look up the modulo operator or even do with out it.
If someone can't do it at all there's some kind of serious issue with the way they're approaching the problem, or perhaps they're just not capable of doing it.
But another common way for people to fail or at least get red-flagged is to over-think it and come up with a turgid solution-- like using lambda calculus!
Simple problem. Simple solution. Nothing fancy. Going against that is asking for failure.
Lambda calculus isn't a "solution" to fizz buzz, it's just another language you can implement fizz buzz in, which is what the parent poster was likely intending to demonstrate.
The lambda calculus approach provides an answer that is a theoretical solution for multiple programming languages. With very minor changes the same answer can apply to C Lang or JavaScript.
I'm a bit confused, how did you implement let, if, else etc.? I don't really know much about the lambda calculus except for what I learned from a short youtube video.
There's a good elaboration of it in Tom Stuart's "Programming With Nothing" talk[0], in which he does a lambda calculus implementation of FizzBuzz in what's left of Ruby if you leave everything out except the things strictly necessary to do lambda calculus - with the exception of what you could call C-style macros (basically text search-and-replace, so you can call a section of code FOO and just type FOO everywhere you would have typed that section of code). There's also the little matter of output - you need to translate the resulting Church numerals into readable form for those who can't see that you've obviously produced correct FizzBuzz. There's a good enough explanation that what needs to be sort of hand-waved for brevity (things that are shown but not really explained in detail) aren't entirely opaque - you will be able to figure it out.
Keep in mind, too, that the lambda calculus is a lot like machine language in one respect - the same little bit of "code" can have more than one meaning to the programmer even if the "machine" is doing exactly the same thing.
This names the identity function id. You can make this slightly prettier like
(\let. ...) (\def body. body def)
Which lets you do
let (\x. x) \id. ...
Booleans are also functions
let (\t f. t) \true.
let (\t f. f) \false.
let (\x. x) \then.
let (\x. x) \else.
let (\b thenLit ift elseLit iff. b ift iff) \if.
Which lets you write
if true then foo else bar
Where then and else are thrown away, without them it is basically lisp syntax. You could make this slightly fancier - translate into cps to support `else if` and require `end` at the end.
Your bash example could be a little cleaner. Since 0 is truthy in bash and [ `expr something` ] is, for most purposes, (( )).
for i in {1..100}; do
if (( $i % 3 && $i % 5 )); then
echo FizzBuzz
elif (( $i % 3 )); then
echo Fizz
elif (( $i % 5 )); then
echo Buzz
else
echo $i
fi
done
Bash also has a decently powerful matching statement so you can do something similar to the rust example.
for i in {1..100}; do
case "$(( $i % 3 ))$(( $i % 5 ))" in
00)
echo FizzBuzz
;;
0*)
echo Fizz
;;
*0)
echo Buzz
;;
*)
echo $i
;;
esac
done
Select Case When SomeNumber % 3 = 0 and SomeNumber % 5 = 0 Then 'FizzBuzz'
When SomeNumber % 3 = 0 Then 'Fizz'
When SomeNumber % 5 = 0 Then 'Buzz'
Else Convert(VarChar(10), SomeNumber)
End As Answer
From (
Select Top 100
SomeNumber = Row_Number() Over (Order By [object_id])
From sys.all_objects
) as Answers
with Ada.Text_IO;
procedure FizzBuzz_Predicate is
subtype Div_3 is Integer
with Dynamic_Predicate => Div_3 mod 3 = 0;
subtype Div_5 is Integer
with Dynamic_Predicate => Div_5 mod 5 = 0;
begin
for i in Integer range 1 .. 99 loop
if i in Div_3 and i in Div_5 then
Ada.Text_IO.Put_Line ("FizzBuzz");
elsif i in Div_3 then
Ada.Text_IO.Put_Line ("Fizz");
elsif i in Div_5 then
Ada.Text_IO.Put_Line ("Buzz");
else
Ada.Text_IO.Put_Line (Integer'Image (i));
end if;
end loop;
end FizzBuzz_Predicate;
As long as you don't try to change the indentation level within a block, it's allowed. It is, however, a style frowned upon -- you should be consistent and use always the same ammount of indentation for blocks. There are a few styles regarding multiline statements though.
FYI: I compiled a free (online) anthology / book about FizzBuzz titled "FizzBuzz (1, 2, Fizz, 4, Buzz,...) by Example - There's More Than One Way To Do It" [1]. Note, all examples are in ruby. Enjoy. Happy new year. Cheers. Prost.
[1]: https://yukimotopress.github.io/fizzbuzz
Minor correction: brainfuck implementations generally provide 30,000 one-byte cells, but opinions differ; some provide more, or provide an unlimited tape. See https://esolangs.org/wiki/Brainfuck#Memory_and_wrapping for more.
const std = @import("std");
pub fn main() u8 {
@setEvalBranchQuota(2000);
const precomputed_output = comptime fizzbuzz: {
var s: []const u8 = "";
var i: usize = 1;
while (i <= 100) : (i += 1) {
if (i % 3 == 0 and i % 5 == 0) {
s = s ++ "FizzBuzz\n";
} else if (i % 3 == 0) {
s = s ++ "Fizz\n";
} else if (i % 5 == 0) {
s = s ++ "Buzz\n";
} else {
var buf: [20]u8 = undefined;
const n = buf[0..std.fmt.formatIntBuf(&buf, i, 10, false, 0)];
s = s ++ n ++ "\n";
}
}
break :fizzbuzz s;
};
const stdout = std.io.getStdOut() catch return 1;
stdout.write(precomputed_output) catch return 1;
return 0;
}
> The entire program is 1 write syscall that outputs the answer. I don't think it's theoretically possible to get faster than that.
If stdout happens to be a socket, setsockopt + SO_SNDBUF might help runtime. But that is an extremely byzantine scenario. Another consideration might be a fast CPU attached to a fast but tiny icache and dcache with very slow memory, where reading the pregenerated string is slower than computing it.
Someone should make a tabletop game inspired by FizzBuzz. Or maybe a card game. It should have "bins" as a mechanic. Maybe change the name to include "bin" in it. Throw in 60's science fiction TV aesthetics and 30's gangsters.
Personally I prefer a fizz buzz that doesn’t make them variables. The loop is so small and it’s obviously never “hot” enough code to make it worthwhile to pull the variables out. It looks like over-optimization to me.
I agree, but for different reasons. I have seen a lot of code start with variables like `divisible_by_three`, only to have the requirements change to check division by 4, but programmers being too lazy to update the variable name as well.
The Rust example looks a bit strange, since you're matching on a variable, but don't actually use it.
Instead, you could write the match like this:
...or even like this: Furthermore, inclusive ranges can be written like this: