Last month Grant Crofton popped down from Leeds to the F#unctional Londoners meetup at Skills Matter to run a fun hands on code golf session. The idea of code golf is to implement a specific algorithm in the fewest possible characters. This is not the kind of thing you should be doing in enterprise code, but it is fun, and an interesting way of exploring features in a programming language.
On the night we attempted condensed versions of FizzBuzz and 99 bottles of beer, with Ross and I winning the first challenge and Simon & Adrian the second.
Thanks again to Grant for a really fun session.
F# FizzBuzz
A while back I strived to squeeze an F# implementation of FizzBuzz into a tweet, and with white space removed it weighs in at 104 characters (excluding line breaks):
for n=1 to 100 do
printfn"%s"
(match n%3,n%5 with 0,0->"FizzBuzz"|0,_->"Fizz"|_,0->"Buzz"|_,_->string n)
The implementation, although quite clear, requires a fair number of characters for the pattern matching portion.
After some head scratching we came up with the idea of using a lookup to select the string to display:
N %3 |
N % 5 |
Index |
Output |
0 |
0 |
0 |
N |
>0 |
0 |
1 |
“Fizz” |
0 |
>0 |
2 |
“Buzz” |
>0 |
>0 |
3 |
“FizzBuzz” |
This took the implementation down to 89 characters (without line breaks):
for i=1 to 100 do
printfn"%s"["FizzBuzz";"Buzz";"Fizz";string i].[sign(i%5)*2+sign(i%3)]
Another trick is to abuse the sign function, to get 1 if the result of the modulus is above 0 and 0 otherwise.
The lookup trick can be used in other languages, and here’s a few examples, just for fun.
VB.Net FizzBuzz
VB.Net has a reputation for being a little verbose, but using the lookup trick it was possible to it get down to 96 characters (excluding line breaks):
For i=1 To 100:
Console.WriteLine({i,"Fizz","Buzz","FizzBuzz"}(-(i Mod 3=0)-(i Mod 5=0)*2))
:Next
In VB.Net true values translate to –1 and false to 0. This allowed me to simply negate the result of i % N = 0 to compute an index.
Python FizzBuzz
Using a similar trick in Python, where true translates to 1 and 0 to false, I was able to get to a very respectable 79 characters (excluding line breaks):
for x in range(1,101):
print([x,"Fizz","Buzz","FizzBuzz"][(x%3==0)+2*(x%5==0)])
Python’s simple print function also helped to keep the character count down.
Amanda FizzBuzz
Amanda is a variant of David Turner’s quintessential functional programming language Miranda. Amanda runs on Windows, and is used for teaching FP at some universities.
Using a list comprehension it was possible to squeeze in to a mere 67 characters:
[["FizzBuzz","Buzz","Fizz",itoa x]!(min[1,x%3]+min[1,x%5]*2)|x<-[1..100]]
Note: this is cheating a little as we are not explicitly writing to the console.
APL FizzBuzz
APL is a very mature language, dating back to the 1960s, and is still used commercially today. It also wins hands down in code golf with just 54 characters:
⍪{'FizzBuzz' 'Buzz' 'Fizz'⍵[1+(2×1⌊5|⍵)+1⌊3|⍵]}¨⍳100
APL is particularly strong at matrix processing and provides single character representations for common operations:
Notation |
Name |
Meaning |
⍳B |
Index generator |
Creates a list from 1 to B |
¨ |
Each |
for each loop |
⍪ |
Table |
Produces a one column matrix |
⌊B |
Floor |
Greatest integer less than or equal to B |
Try APL in your browser now.
Challenge
Can you beat the APL implementation of FizzBuzz?
Have fun!