Implementing Fizz Buzz in JavaScript

Implementing Fizz Buzz in JavaScript

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 returns true and logs the number to the console after which starts the next iteration. If it returns false,

  • 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 returns false,

  • 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 returns false , then

  • At 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 numbers

  • a recursive function named recursiveConverter which is the "backbone" of the entire converter function. This recursive function takes two parameters, baseTenNumber and base are serving the same purpose as the parameters in the parent converter function.

How does the recursiveConverter function work?

  • It first checks if baseTenNumber is lesser than base .If true, then:

    • baseTenNumber is now appended at the end of the convertedNumString variable

    • convertedNumString is then split using the JavaScript array method split() to turn it into an array, reversed using the JavaScript array method reverse() 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 using join() 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 in convertedNum.

    • recursiveConverter then returns convertedNum .

  • If baseTenNumber is greater than base , 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 the convertedNumString variable

    • It then updates the baseTenNumber variable by performing a simple mathematical operation, (baseTenNumber - (baseTenNumber % base)) / base on it before calling recursiveConverter 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!