Fizz… Buzz… FizzBuzz!
Last evening, I ended up on YouTube… Don’t worry, I am not going to tell you about that cat falling off a table, I promise!
Amongst my suggested videos was one from Tom Scott. If you don’t know him, his YouTube channel covers a lot of sciences, (nerdy) fun facts and other computer-related topics… Definitely worth a follow if you ask me!
As I was saying, I came across his (now) old videos: FizzBuzz: One Simple Interview Question.
And I thought I should give it a go… so did I! I also had a look around, and I came across a lot of posts and articles about people reflecting on that specific interview question. If you are interested, see the links at the bottom of the page.
I wasn’t familiar with the FizzBuzz game and, if like me, you aren’t either, here are the rules of the game:
The game is played between 2 people, each counting in turn. Every time:
- A multiple of 3 comes up, the number is replaced by “Fizz”.
- A multiple of 5 comes up, the number is replaced by “Buzz”.
- A multiple of 3 and 5 comes up, the number is replaced by “FizzBuzz”.
The idea is to write a program that prints the numbers, substituting the multiples of 3 and 5 by “Fizz”, “Buzz”, and “FizzBuzz” accordingly.
Putting the rules as bullet points has pretty much done the trick. Instinctively I would write a program with 3
if statements. I know that having the clauses in this order wouldn’t work as the combined membership (multiple of 3 AND 5) needs to be checked beforehand otherwise, all the “FizzBuzz” instances will appear as “Fizz”, as the multiple of 3 test is
A few other things worth noting:
- We are going to run this program for numbers up to 100, using
range()is 0-indexed, we need to specify the starting number
1(inclusive) and the finishing number:
- The easy way to test if a number is a multiple of another is to use the
% (modulo operator). This operator returns the rest of the division. When the rest of the division is zero, we have our multiple!
Altogether, we end up with this code:
Because I am a big fan of list comprehensions, and because ordering the
if statements in decreasing order is doing half the job already, I thought I would give this code a quick polish with list comprehension:
In under 2 minutes, we’ve managed to have a readable, fast, and refactored FizzBuzz program… Well done!
But wait a minute! The interview is not over yet, and this question was answered so quickly, there is a lot of time for follow-up questions!
As Tom mentions later in his video, this approach gets a bit tricky when the parameters change: what if we need multiples of 11 to be “Fizz”? How many alterations do we need to make to the code? Is this easy to maintain when the code is 500 lines long?
One of the answers to this is to reduce the number of if statements by using string properties (the one suggested in the video):
The final print statement will ensure only a non-empty object will be printed:
- The number itself,
i, when not a multiple of 3 or 5.
Fizzwhen divisible by 3 (only).
Buzzif divisible by 5 (only).
FizzBuzzif divisible by 3 and 5.
i % 3changes answer to
Fizz, then as the condition
1 % 5is also met,
Buzzgets added (concatenated) to the string.
The advantage of this solution is there is only one place where the code needs to be altered to either add a rule (copy-paste and change value), either modify a value (e.g. change
11 for our initial follow up question).
Fair enough, but we are talking Python here… It would be a shame not to use this brilliant data type called “dictionary”! Imagine having a dictionary containing the rules, how easy would this be for maintaining the code? Also, let’s add a little bit of flexibility by asking the user what range is considered:
In this code, we reduce the many if statements to a single one by:
- Piggybacking on the idea of string concatenation.
- Using the concept of pair
We solve fetching the user input by “phrasing” this code into a function.
Altogether, I think this makes for a neat solution! No matter how many rules are (easily) added, no matter how regularly the values need to be changed, this code is future-proof!
Thanks for reading!