FizzBuzz in ten languages
iolivia.me
iolivia.me
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:
let div_by_three = x % 3 == 0;
let div_by_five = x % 5 == 0;
match (div_by_three, div_by_five) {
(true, true) => println!("FizzBuzz"),
(true, false) => println!("Fizz"),
(false, true) => println!("Buzz"),
_ => println!("{}", x),
}
...or even like this: match (x % 3, x % 5) {
(0, 0) => println!("FizzBuzz"),
(0, _) => println!("Fizz"),
(_, 0) => println!("Buzz"),
_ => println!("{}", x),
}
Furthermore, inclusive ranges can be written like this: for x in 1..=100 {Did the author change it?
Edit: just saw the comments on the article. Yes, she did.
for x <- 1..100 do
case [rem(x, 3), rem(x, 5)] do
[0, 0] -> IO.puts("FizzBuzz")
[0, _] -> IO.puts("Fizz")
[_, 0] -> IO.puts("Buzz")
_ -> x
end
end def fizzbuzz
[1, 2, "Fizz", 4, "Buzz", "Fizz", 7, 8, "Fizz", "Buzz", 11, "Fizz", 13, 14,
"FizzBuzz", 16, 17, "Fizz", 19, "Buzz", "Fizz", 22, 23, "Fizz", "Buzz", 26,
"Fizz", 28, 29, "FizzBuzz", 31, 32, "Fizz", 34, "Buzz", "Fizz", 37, 38,
"Fizz", "Buzz", 41, "Fizz", 43, 44, "FizzBuzz", 46, 47, "Fizz", 49, "Buzz",
"Fizz", 52, 53, "Fizz", "Buzz", 56, "Fizz", 58, 59, "FizzBuzz", 61, 62,
"Fizz", 64, "Buzz", "Fizz", 67, 68, "Fizz", "Buzz", 71, "Fizz", 73, 74,
"FizzBuzz", 76, 77, "Fizz", 79, "Buzz", "Fizz", 82, 83, "Fizz", "Buzz", 86,
"Fizz", 88, 89, "FizzBuzz", 91, 92, "Fizz", 94, "Buzz", "Fizz", 97, 98,
"Fizz", "Buzz"]
end
Source: https://yukimotopress.github.io/fizzbuzz#gold-standard auto fizzbuzz(size_t n) {
return iota(n)
.map!((i) {
if ((i % 15) == 0) {
return "FizzBuzz";
} else if ((i % 3) == 0) {
return "Fizz";
} else if ((i % 5) == 0) {
return "Buzz";
} else {
return i.to!string;
}
});
}
void main() {
// enum here forces compile-time execution
enum fizzbuzz100 = fizzbuzz(100).join("\n");
writeln(fizzbuzz100);
} $ date +%A
Tuesday
$ anyfizzbuzzprogram > fizzbuzz100
$ cat fizzbuzz100
[output]
$ date +%A
Wednesday
$ cat fizzbuzz100
[output]
:-)Pshaw.
This thread is utterly incomplete without Fizz Buzz Enterprise Edition™[1].
If you want to get straight to the good parts of it, just look at the Factories folder[2].
[1]https://github.com/EnterpriseQualityCoding/FizzBuzzEnterpris...
[2]https://github.com/EnterpriseQualityCoding/FizzBuzzEnterpris...
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)
(define wheel '(#f #f "fizz" #f "buzz" "fizz" #f #f "fizz" "buzz" #f "fizz" #f #f "fizzbuzz"))
(for ((fb? (in-cycle wheel)) (i (in-range 1 101)))
(displayln (or fb? i)))
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.
(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.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.
fb :: (Integer, Integer) -> String
fb (mod3, mod5)
| (0, 0) = "FizzBuzz"
| (0, _) = "Fizz"
| (_, 0) = "Buzz"
| otherwise = show n
main = putStrLn $ unlines $ map fb $ map (\x -> (x % 3, x % 5)) [1..100] def fizzbuzz(n):
case (n % 3, n % 5):
match (0, 0): return "FizzBuzz"
match (0, _): return "Fizz"
match (_, 0): return "Buzz"
else: return n |> str
(
range(1, 100)
|> map$(fizzbuzz)
|> x -> '\n'.join(x)
|> print
) for val in xrange(1, 100):
if val % 15 == 0:
print "FizzBuzz"
elif val % 5 == 0:
print "Buzz"
elif val % 3 == 0:
print "Fizz"
else:
print valSo the statements are equivalent in whole, but the difference is that a match statement requires less reading (as it holds more meaning)
Sometimes boring code beats clever code.
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.
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.
https://github.com/jongeorge1/FizzBuzzEnterpriseEdition-CSha...
puts (1..100).map { |i| (fb = [["Fizz"][i % 3], ["Buzz"][i % 5]].compact.join).empty? ? i : fb }
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
(Yes, that's actually source code.) for x in range(1, 101):
out = ""
if x % 3 == 0:
out += "Fizz"
if x % 5 == 0:
out += "Buzz"
print(out or x) print('\n'.join([
'fizzbuzz' if x%15 == 0 else
'fizz' if x%3 == 0 else
'buzz' if x%5 == 0 else
str(x)
for x in range(1, 101)]))
Or for x in ['fizzbuzz' if x%15 == 0 else
'fizz' if x%3 == 0 else
'buzz' if x%5 == 0 else
x for x in range(1, 101)]:
print xprint('\n'.join([{(True, False): 'Fizz', (False, True): 'Buzz', (True, True): 'FizzBuzz'}.get((i % 3 == 0, i % 5 == 0), str(i)) for i in range(1, 101)]))
Java, VBA, php, cobol, forth, C++, brainfuck, python, Groovu, BASIC, JavaScript, CoffeeScript, sh, PowerShell, Clojure, Ruby, C#, Haskell, ABAP, Lua, Matlab, Common Lisp, Oracle PL/SQL, Scala, F#, Bash, C, LOLCODE, golang, Enterprise Java, MySQL, Visual FoxPro, Perl, shakespeare
Of course, if you want it in Malboge [1], you can refer to a prior HN discussion [2] of FizzBuzz in multiple languages.
[0] http://wiki.c2.com/?FizzBuzzTest
(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! for n in range(1, 101):
print(n, end='\r')
if n % 3 == 0:
print("Fizz", end='')
if n % 5 == 0:
print("Buzz", end='')
print()Here's one way to do it:
% e.g. place in metagol/examples/
:-['../metagol'].
% Second-order inductive bias.
metarule([P,Q],([P,A,A]:-[[Q,A]])).
metarule([P,Q,B,C],([P,A,B]:-[[Q,A,C]])).
% Learning primitives.
prim(positive_integer/1).
prim(exact_division/2).
% Primitives' definitions.
positive_integer(N):-
between(1,inf,N).
exact_division(X,Y):-
positive_integer(X)
,divisor(Y)
,0 is X mod Y.
divisor(3).
divisor(5).
divisor(15).
% Training setup.
learn_fizzbuzz:-
% Positive examples
Pos = [fizzbuzz(1,1)
,fizzbuzz(2,2)
,fizzbuzz(3,fizz)
,fizzbuzz(5,buzz)
,fizzbuzz(15,fizzbuzz)
]
% Negative examples
,Neg = [fizzbuzz(1,fizz)
,fizzbuzz(1,buzz)
,fizzbuzz(3,fizzbuzz)
,fizzbuzz(5,fizzbuzz)
]
% Train with metagol
,learn(Pos,Neg).
We can put that in a file, consult it and call learn_fizzbuzz at the Prolog repl: ?- learn_fizzbuzz.
% learning fizzbuzz/2
% clauses: 1
% clauses: 2
% clauses: 3
% clauses: 4
fizzbuzz(A,fizzbuzz):-exact_division(A,15).
fizzbuzz(A,buzz):-exact_division(A,5).
fizzbuzz(A,fizz):-exact_division(A,3).
fizzbuzz(A,A):-positive_integer(A).
true .
This will give us the fizzbuzz/2 function, mapping each integer N to {fizz,buzz,fizzbuzz,N}. Then we can simply loop over it: print_fizzbuzz(N):-
forall(between(1,N,I)
,(fizzbuzz(I,FBN)
,writeln(FBN)
)
).
Note we learned a general version of fizzbuzz from only 5 positive and 4 negative examples. Just don't tell Joel Grus [2]._______
(defn fizzbuzz [x]
(cond-> nil
(zero? (mod x 3)) (str "Fizz")
(zero? (mod x 5)) (str "Buzz")
:always (or (str x))))
(doseq [x (range 1 101)] (prn (fizzbuzz x)))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.Call it like this:
?- print_fizzbuzz(1,100).
And have a Happy New Year.Also we have the teapot, hello world, Foo Bar
What are some others?
Atwood referenced Imran Ghory who seems to have originated the test.
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.
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)
I always enjoy how lambda calculus suddenly becomes a readable language after the prelude:
let (\n.
let (\m. isZero (mod n m)) \divisibleBy.
if (and (divisibleBy 3) (divisibleBy 5))
then FizzBuzz
else
(if (divisibleBy 3)
then Fizz
else
(if (divisibleBy 5)
then Buzz
else (intToStr n))))
\fizzBuzzStep.
(loop \recurse. \n.
if (equals n 100)
then nil
else (cons (fizzBuzzStep n) (recurse (n+1)))
) 1)
(\letArg letBody. letBody letArg)
let, if, then, else, loop, and even the numbers are all functions.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.
(\id. ...) (\x. x)
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.Tl;dr: with hacks
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.
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
doneHNY! (:
#/bin/bash
for n in {1..100} ; do
f=""
((n % 3)) || f="Fizz"
((n % 5)) || f="${f}Buzz"
echo ${f:-$n}
done #!/bin/bash
for n in {1..100}; do
f=
((n % 3)) || f=Fizz
((n % 5)) || f+=Buzz
echo ${f:-$n}
doneif ((0)); then echo 0=true; else echo 0=false; fi
if ((1)); then echo 1=true; else echo 1=false; fi
# output
0=false
1=true
To work as expected, the if statements should be rewritten as
if ((i % 3 == 0 && i % 5 == 0)); then echo FizzBuzz
and so on.
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 public interface Matcher {
Optional<String> match(int value);
static Matcher divideBy(int div, String text) {
return value -> Optional.of(value).filter(v -> v % div == 0).map(__ -> text);
}
default Matcher zip(Matcher matcher, BinaryOperator<String> op) {
return value -> Stream.of(match(value), matcher.match(value)).flatMap(Optional::stream).reduce(op);
}
public static void main(String[] args) {
var matcher = divideBy(3, "Fizz").zip(divideBy(5, "Buzz"), String::concat);
IntStream.rangeClosed(0, 100)
.mapToObj(value -> matcher.match(value).orElse("" + value))
.skip(1).forEach(System.out::println);
}
} 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; x <- 1:100
case_when(
x %% 35 == 0 ~ "fizz buzz",
x %% 5 == 0 ~ "fizz",
x %% 7 == 0 ~ "buzz",
TRUE ~ as.character(x)
)I didn't think python would allow this, but apparently it does!
echo '#include <stdio.h>' > fb.c
./fizzbuzz > buf
xxd -i buf >> fb.c
echo 'int main(void) { return fwrite(buf, buf_len, 1, stdout) != 1; }' >> fb.c 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;
}
Output: $ zig build-exe fizzbuzz.zig
$ ./fizzbuzz
<correct output>
$ strace ./fizzbuzz
execve("./fizzbuzz", ["./fizzbuzz"], 0x7ffeeb1a4540 /* 132 vars */) = 0
write(1, "1\n2\nFizz\n4\nBuzz\nFizz\n7\n8\nFizz\nBu"..., 4131
exit(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.
(They're golfed, meaning bytecount is minimized.)