in javascript programming ~ read.

How many ways can you FizzBuzz?

One of the most common coding interview questions is the FizzBuzz. It essentially demonstrates that you have a basic knowledge of looping and if/else statements.

The Problem:

  1. print all of the numbers from 1-100
  2. If a number is divisible by 3 print the number followed by 'fizz'
  3. If a number is divisible by 5 print number followed by 'buzz'
  4. If a number is divisible by 15 print number followed by 'fizz buzz'

The Canonical Implementation

the easiest way to to this (if you have enough coffee and haven't forgotten how to write for loops looks like this)

for (var i =0; i <= 100; i++){  
  if ((i % 15) === 0 ){
    console.log(i, 'fizz buzz');
  }
  else if ((i % 3) === 0 ){
    console.log(i, 'fizz');
  }
  else if ((i % 5) === 0 ){
    console.log(i, 'buzz');
  }
  else {
   console.log(i)
  }
}

Benefits

  • This implementation is pretty readable you know exactly what it does

Downsides

  • This implementation has quite a log of repetition
  • Also I'm not crazy about a long of if/else statements in a row. This is often a code smell for something that could be simplified and made more readable

Take 2 An Array Based Approach

Let's see if we can't remove some of that repetition

var output;  
for (var i =0; i <= 100; i++){  
  output = [i];

  if ((i % 3) === 0 ) { output.push('fizz'); }
  if ((i % 5) === 0 ) { output.push('buzz'); }

  console.log(output.join(' '));
}

Benefits

  • This one is a bit cleaner. There are less clauses
  • We've removed the repetition
  • We've shown that we can use arrays

Downsides

  • we have added a new array into the mix, not too memory intensive, but not quite as fast as the previous example
  • Maybe too complex for a newbie that doesn't understand Array.join? ... but this is a coding interview. So we'll move on

Possible Upgrades

  • If we were using es6/es2015, we could remove var output; outside our loop and used let output = [i]; inside the loop instead.
  • At this point our code still looks rather procedural. This could easily be a couple of functions. What if we wanted to vary the number of times in the loop or wanted to print other text?
  • ... Our could we make this more functional? FP is all the rage these days.

Confession

It was at about this point, that I grew bored of writing this post and googled around for functional fizzbuzz examples. I found this entertaining article by Tom Dalling. This probably influenced all of my examples. And, it just goes to show that this post isn't really that unique.

Back to the Code!

A Parameterized example

This one definitely takes a bit from the aforementioned example. But what if we want a variable number of loops, variable conditions and variable words?

/**
* @param loops - number of times to run the fizzbuzz
* @param conditions - Array of objects that contain:
* condition - An anonymous function that will return a boolean
* word - the word to add to output when condition is true  
**/
function fizzbuzz(loops, conditions = []){  
  var output = [];
  var word;

  for (var i =0; i <= loops; i++) {
    word = conditions.map( function(c){ 
      if ( c.condition(i) ) 
      { return c.word; }  
      return ''; 
    })
    output.push([i, word].join(' '));
  }

 return output;
}

var log = fizzbuzz(100, [  
  {condition: function(i){ return ((i % 3) == 0) }, word: 'fizz'}, 
  {condition: function(i){ return ((i % 5) == 0) }, word: 'buzz'}
]);

console.log(log);  

Benefits

  • We now have a variable loop number and variable conditions
  • We have something that is potentially more testable

Downsides

  • It's not immediately understandable how to use this function.
  • This implementation doesn't strictly adhere to the directions (there's a random comma being thrown in for some reason)

Possible Upgrades

  • Fix the comma bug
  • Come up with something more easily understandable

Conclusion

I suppose I could go further. But in reality the whole point of the exercise is to show that you have a basic understanding of control structures. Maybe it's best to be simple.

comments powered by Disqus