The most elegant implementation of FizzBuzz
What is FizzBuzz?
FizzBuzz test is an interview question designed to help filter out the 99.5% of programming job candidates who can't seem to program their way out of a wet paper bag.
The text of the programming assignment is as follows:
Write a program that prints the numbers from 1 to 100. But for multiples of three print “Fizz” instead of the number and for the multiples of five print “Buzz”. For numbers which are multiples of both three and five print “FizzBuzz”
There are a lot of ways to write the
FizzBuzz program. See for instance the one using clojure pattern matching.
Today, I'd like to share with you the most elegant implementation of FizzBuzz I ever seen. It's elegant because it doesn't make use of any imperative constructs (like
if statements), but only functional programming constructs (like infinite lazy sequences and function composition).
This implementation was developed by Dierk König and Kevlin Henney presented a
Haskell version of it - in his amazing talk Declarative Thinking, Declarative Practice.
In this article, we are going to present an interactive version of Kevlin's code in
The elegant code
Take a look at this marvel: no
if statements - only 3 infinite lazy sequences and function composition.
This is exactly what we call - Purely Functional:
And it works like a charm:
Feel free to modify
19 - the code snippets are live and interactive powered by the klipse plugin:
- Live: The code is executed in your browser
- Interactive: You can modify the code and it is evaluated as you type
If you are a bit skeptic (yet) about the elegance of this implementation, you might want to read Dierk König's article: he explains in details the pragmatic advantages of his code.
You probably wonder what is this
choice function and why does
max do when it receives 2 strings?
clojurescript runs on top of
(> "abc" "")
But that is an ugly trick - that doesn't work in
clojure. So it's much better to use the
choice function - that returns the first non-empty string of the two it receives:
(choice "abc" "")
And it works also: