FizzBuzz is a programming task based on a game for teaching children about division. It is a simple and popular task that is used to filter out unqualified programmers during software engineering interviews. It has different variations which have little quirks that differentiate them from the original. In this article,
We will be implementing the original version.
We will be modifying the original version by printing all non-multiples out in base 2 (binary).
If you are reading this article now, you might have implemented it at least once and might want to look at it again. If you have never, read on to find out how.
Rules of FizzBuzz.
FizzBuzz is a basic counting and division task that follows the following rules:
Numbers divisible by 3 are replaced by "Fizz".
Numbers divisible by 5 are replaced by "Buzz".
Numbers divisible by both 3 and 5 are replaced by "FizzBuzz".
All other numbers are counted as they are.
Other variations might have rules which are slightly different but are based on the above set of rules.
Coding FizzBuzz
For a given range of numbers 1-100, the rules of FizzBuzz can be translated into the following logical statements:
If a number is a multiple of 3, print "Fizz",
Else if a number is a multiple of 5, print "Buzz",
Else if a number is a multiple of 3 and 5, print"FizzBuzz",
Else, print the number.
A direct translation of the above statements into code is shown below:
for (let x = 1; x <= 100; x++) {
//Filter out the numbers indivisible by either 3 and 5
if (!(x % 3 == 0) && !(x % 5 == 0)) console.log(x);
//Filter out numbers divisible by 3 and 5
else if ((x % 3 == 0) && (x % 5 == 0)) console.log("FizzBuzz");
//Filter out numbers divisible by 3
else if (x % 3 == 0) console.log("Fizz");
//Filter out numbers divisible by 5
else if (x % 5 == 0) console.log("Buzz");
}
This is FizzBuzz. In the code block above, a for loop is used to iterate through the range of numbers 1-100. For each number in the specified range, an if-else if
block is used to evaluate:
If the number is not a multiple of both 3 and 5. This is achieved by the modulo operator
%
which checks the divisibility of the number by 3 and 5. If the number is indivisible by 3 and 5, then it returnstrue
and logs the number to the console after which starts the next iteration. If it returnsfalse
,The next statement checks if the number is a multiple of both 3 and 5 by checking its divisibility by both 3 and 5. If this statement returns
true
, then"FizzBuzz"
is logged into the console. Else if it returnsfalse,
The third statement checks if the number is a multiple of 3 by checking its divisibility by 3. If
true
is returned, then"Fizz"
is logged into the console. If it returnsfalse
, thenAt this point, the number can be assumed to be a multiple of 5 since all other possibilities have been eliminated in the preceding statements of the
if-else if
block. The last statement checks if the number is divisible by 5. If true, then"Buzz"
is logged into the console.
At the end of the process, a result like this will be returned:
- So, all of the above is the implementation of the traditional version of the FizzBuzz algorithm. Let's go and try to implement the modification.
Modifying FizzBuzz
What if we decided to output the numbers which do not satisfy any of the rules of FizzBuzz in another number base apart fom base 10 (decimal)? Then we would need to have a function that would convert all such numbers from base 10 to other number bases.
How does conversion from base 10(decimal) to other bases work? It is a process that involves repetitive division of the number you want to convert by the base to which you are converting, followed by the writing of the remainder from each step of the division process as a single number. For example, if we wanted to convert 8 to a binary number then we could calculate it as follows:
8 divided by 2 gives 4, the remainder is 0
4 divided by 2 gives 2, the remainder is 0
2 divided by 2 gives 1, the remainder is 0
1 divided by 2 gives 0, the remainder is 1
Writing all the remainders as a single number from down to top gives you your answer in binary which is 1000
. Implementing this in JavaScript would require using a recursive function to handle the repetitive division as illustrated in the code block below:
function converter(baseTenNumber, base) {
let convertedNumString = "";
function recursiveConverter(baseTenNumber, base) {
if (baseTenNumber < base) {
convertedNumString += `${baseTenNumber}`;
let convertedNumber = Number(
convertedNumString.split("").reverse().join("")
);
return convertedNumber;
} else {
convertedNumString += baseTenNumber % base;
baseTenNumber = (baseTenNumber - (baseTenNumber % base)) / base;
return recursiveConverter(baseTenNumber, base);
}
}
return recursiveConverter(baseTenNumber, base);
}
In the code block above, we have a function named converter
which takes two parameters:
baseTenNumber
which is the decimal number you are converting and,base
, which is the number base you are converting to.
It contains:
convertedNumString
, which is an empty string for holding the remainder of each step in the repetitive division process temporarily before they are converted into numbersa recursive function named
recursiveConverter
which is the "backbone" of the entire converter function. This recursive function takes two parameters,baseTenNumber
andbase
are serving the same purpose as the parameters in the parentconverter
function.
How does the recursiveConverter
function work?
It first checks if
baseTenNumber
is lesser thanbase
.If true, then:baseTenNumber
is now appended at the end of theconvertedNumString
variableconvertedNumString
is then split using the JavaScript array methodsplit()
to turn it into an array, reversed using the JavaScript array methodreverse()
to reverse the order of the string (This is necessary, to follow the down-to-top arrangement of the remainders. In this case, it becomes right-to-left.) and finally joined usingjoin()
which is also a JavaScript array method to turn it back into a string from an array after which it is converted to a number using the Number object for converting strings to numbers and stored inconvertedNum
.recursiveConverter
then returnsconvertedNum
.
If
baseTenNumber
is greater thanbase
, then it proceeds to evaluate the else block:By finding the remainder of
baseTenNumber
in the current stage of the repetitive division process and appending it to theconvertedNumString
variableIt then updates the
baseTenNumber
variable by performing a simple mathematical operation,(baseTenNumber - (baseTenNumber % base)) / base
on it before callingrecursiveConverter
again.
It repeats the above process until the condition in the if
block of the recursiveConverter
has been satisfied.
Calling the converter
function in our FizzBuzz code
Finally, it's time to apply the base converter function in our existing FizzBuzz code. It is as simple as changing the first line in our FizzBuzz code so the entire code block becomes the one below:
for (let x = 1; x <= 100; x++) {
//Filter out the numbers indivisible by either 3 and 5 and output them
// as binary numbers using converter function.
if (!(x % 3 == 0) && !(x % 5 == 0)) console.log(converter(x, 8));
//Filter out numbers divisible by 3 and 5
else if (x % 3 == 0 && x % 5 == 0) console.log("FizzBuzz");
//Filter out numbers divisible by 3
else if (x % 3 == 0) console.log("Fizz");
//Filter out numbers divisible by 5
else if (x % 5 == 0) console.log("Buzz");
}
In the snippet above, base
was set to 8. Running it would give the result below:
Conclusion
There are several ways you could modify the code in this article. You could:
Change the divisors from 3 and 5 to other numbers
Conduct all calculations in another number base and provide output in decimal.
Modify
recursiveConverter
to convert decimals to hexadecimal.
Thanks for reading!