FizzBuzz is a simple coding challenge popularized by Jeff Atwood to test for the most basic level of coding ability. The goal of FizzBuzz is simply to print the numbers from 1 to 100, but to replace numbers divisible by 3 with “Fizz”, and those divisible by 5 with “Buzz”. This past Friday, HackerRank launched a FizzBuzz competition with a twist: to solve FizzBuzz with the shortest possible source code, and with each output on a new line. In short, it was a FizzBuzz Code Golf contest. Code Golf focuses on writing the shortest possible code instead of any practical goal, but it can still help coders learn a language well. You need to learn many different features and tricks of a language to do well at Code Golf, and some of this knowledge is useful when writing real code.
The top scorers in the challenge were asked if they could share their code and approach with others, and many graciously agreed. The top languages used to solve the contest were Perl, Ruby and Python, and this post will discuss a solution from each language.
FizzBuzz is a simple “challenge” so even a regular Ruby solution takes up only 90 characters:
The code is quite simple. If a number is divisible by 3 or 5 it will both print the relevant word and set the variable ‘f’ to true. Otherwise, f won’t be initialized, so the 4th line can print the actual number.
This solution isn’t that long, and it doesn’t even use any special “code golf” tricks. By writing in a much more opaque “Code Golf” style, the code can be shortened greatly. The shortest Ruby solution was submitted by Keisuke Nakano (@ksknac) and it uses only 53 characters:
The code ‘puts’ the whole output for each line, so no extra call is needed for a new line character. By using some clever modular arithmetic, it eliminates the need to have separate checks to see if n divides by 3 and 5. Instead, it slices the string to ensure it prints the relevant part, like this: puts’FizzBuzzn’[start,end]. To get the right output, the code makes sure that start equals the following for each n:
- n = multiple of 3: -9
- n = multiple of 5: -5
- n = multiple of 3 and 5: 0
- none of the above: -14 (So the slice will be nil and it will print the number instead.)
Keisuke accomplished this feat with a variation of Fermat’s Little Theorem. By raising n to a power, you can make sure to get the right remainders for each factor. Thus, for each n, n**4%15 will equal:
- n = multiple of 3: 6
- n = multiple of 5: 10
- n = multiple of both 3 and 5: 0
- none of the above: 1
Instead of dividing by 15, the code uses -15, to output the previous results (which are 15 less). Those results work out perfectly to print the correct part of the string, or to get nil when necessary. The extra newline doesn’t harm things, since Ruby’s ‘puts’ method only adds a newline when there wasn’t one there already. It’s a complicated solution, but it’s very short code.
The shortest Python solution was submitted by user fR0DDY (though other users also tied with that length). He started by writing some straightforward but concise code:
He then used a shorter form of the ternary operator in python: [falseVal,trueVal][test], so the ‘if’s’ and ‘else’s’ could be eliminated. Since one of the values is an empty string, the expression can be shortened further in Python to trueVal*test,which will result with nothing if the test is false. This leaves the following code:
for x in range(100):
print ‘Fizz’*(x % 3 == 2) + ‘Buzz’*(x % 5 == 4) or x + 1
The code can then be shortened further by changing the test to return 1 for true and 0 for false. So the first test can be changed to x%3/2 since if x+1 is a multiple of 3, then x%3/2 = 1. Similarly, the second test can be changed to x%5/4 since if x+1 is a multiple of 5, then x%5/4 = 1.
By using a couple more small tricks, the entire code can be shortened to only 55 characters, which is about the same length as the Ruby solution (just clearer!):
You can also view the code on Stypi, and they even have an option to watch it being typed.
While Ruby and Python could both be used for short solutions, the top entries all used Perl, a language known for its conciseness. Multiple people submitted almost identical Perl solutions that used only 48 characters! This is the winning code:
By amazing coincidence, this same solution also appears on PerlMonks, along with some other varieties. Despite its brevity, the code is pretty direct, and you can follow the gist of what’s going on without even knowing Perl.
FizzBuzz is a very simple problem, but there are many different ways to solve it! The top Ruby solution was the most complicated, while the Python and Perl solutions were more direct. To see Code Golf solutions in even more languages, see this blog post. You can also use “normal” FizzBuzz solutions as a simple way to compare different languages. To do this, check out the hundreds of solutions to FizzBuzz on Rosetta Code.