Revealing the design of FizzBuzz
1, 2, Fizz, 4, Buzz…
Is it ‘Fizz’ next? The rules are seemingly simple enough:
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”.” – Imran on Tech
You may have encountered FizzBuzz before. It’s an exercise designed to trip up prospective job candidates.
The traditional fizzbuss.js solution looks like:
All done! Shall we move on? Where do you see yourself in five years time?
I’d like to revisit that solution, please.
I’ve often found that design is hidden underneath conditionals. By removing conditionals, we can reveal the truth about a design that was begging to be discovered.
So how do we rewrite the above solution to no longer use conditionals?
We need to look at what FizzBuzz is all about. The contract we have is to provide a list of values that change based by some repeating rules.
The solution we currently have has one range and four conditionals. Let’s start with one range.
Now let’s repeat the range to fill in the other values upon the result array.
Great. We’ve got no condtionals. Let’s see what the Internet thinks about our solution:
@joe_jag my students will point out that there's duplication in there :)
— The XP Surgery (@xpsurgery) March 10, 2017
(How easy is it to add 7 -> bang ?)
Ouch.
Let’s DRY that up a bit by using the Lodash#range
But @xpsurgery also threw in a curveball of how easy the design is to extend. Let’s try adding the ‘bang’ rules.
Hmm. We got it to work. But it meant adding four new rules. If we added another rule, it’d mean adding another 5 and so on. Cleary this design isn’t that good.
Drat.
But wait. Can you see the pattern that is emerging? Look at the first value we supply to range each time. We are manually creating a combination of the available numbers that FizzBuzz requires.
Wait.
We’ve now discovered the essential design involved in FizzBuzz.
FizzBuzz takes the available combinations for some interesting numbers and generates a list of their repeating values.
So let’s try this again.
First we’ll need a way of generating combinations of numbers. Thankfully npm already has a package for this:
Let’s use a value from this to generate the sort of values we are interested in:
So let’s pull this together:
You’ve probably kicked me out of the interview by now. But I’d argue this solution better represents FizzBuzz and extra rules that follow it’s inherent design.
This may seem minor here, but it real-world code this same pattern of behaviour often forces code to start mirroring real life design.
I’ve argued the case for no ifs before. So I won’t reiterate them here.
Hopefully, this post has encouraged you to try removing some conditionals from your code. If not then enjoy this CSS solution instead.