Ady Ngom
Ady Ngom
May 20 · 9 min read

Like many things in life, mastery requires practice and the coding interview is no exception.

Often times though, the focus is on trying to find the best solution from the get-go rather than the approach on how to iterate and maybe get there.

The most important part, in my humble opinion, is to get it right first. In your normal coding life, you would rarely, if ever, be able to produce “perfect” code without first going through a set of iterations.

The approach during the coding interview should not differ and if played well should help you score invaluable points into demonstrating your problem-solving skills.

I’m going to walk you through of what could be an actual conversation between you and an interviewer if you were asked to solve for the [in]famous FizzBuzz challenge.

The challenge

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

The context

The FizzBuzz challenge is not specific to JavaScript and has been part of the coding interview process in almost every programing language.

It is usually a quick check to assess the candidate basic programming instincts, but can also be turned in an assessment for in-depth knowledge if the interviewer decides to do so.

It is usually part of a lightweight first technical interview done while screen sharing. It is also a favorite from a non-JavaScript programmer to ask and quickly gauge your technical knowledge and approach.

In a Javascript context familiarity with some or all the following concepts are expected to be demonstrated:

  • Logical operators
  • Looping
  • Falsy values
  • Ternary operator
  • Type coercion

The approach

As with any problems that you might encounter, even those that seem familiar, a good read and break down to small pieces is a must. Be clear to the interviewer that you need 3 to 5 minutes to read it calmly and propose a rewrite of your understanding.

If you are comfortable doing that part out loud, that’s even better. For example, this is how I might go for the rewrite:

  • So log to the console numbers from 1 to 100 — I’m going to need a loop
  • For multiple of 3 instead of the number output the string ‘Fizz’
  • Do the same for multiples of 5 with the output being ‘Buzz’
  • In the case the number is a multiple of both 3 and 5 then output ‘FizzBuzz’ — how to check if a is a multiple of b??
  • If all the above cases fail then just output the number as is

I would probably ask the interviewer if I should worry about edge cases or bad inputs.

It is usually implied that the input will be correct and edge cases might not be necessary.

The fact that you ask though, adds a touch of eloquence to your problem-solving approach.

The solution(s)

One thing that is key and is worthy of practice is walking the person through your steps as you are building the solution during the interview.

Start with the obvious, you will probably need a function or class as your primary construct.

Start there and always think of the K.I.A.S.S.A.P :) principle — Keep It As Stupid Simple As Possible

First step

// comments are me talking out loud// let’s build the function structurefunction fizzBuzz( start = 1, end = 100) { // default parameters to set the default range// I need a loop — let’s go with forfor( let i = start; i <= end; i++) {// probably a variable for what will be outputtedlet output = i;// rest of the logic here// outputting the resultconsole.log(output);}}// call the functionfizzBuzz(); // this prints out 1 to 100 — fancy ;)

The above satisfies my first goal on my rewritten challenge understanding

Second step

Now if I follow the cadence of the challenge I will solve for two things:

1. Choosing the proper operator to find if a number is a multiple of another

2. Apply it for the multiple of 3 condition and output ‘Fizz’

The remainder operator — %, is the perfect tool here. If number a is a multiple of number b then

( b % a) === 0; // will be true;// 4 is a multiple of 2( 4 % 2 ) === 0; // is true

Let’s apply this in the body of our function

// rest of the logic hereif( (i % 3) === 0 ) {output = ‘Fizz’;}// Knowing that 3,6 and 9 are multiple of 3 let’s// quickly test a small sequence by callingfizzBuzz(1,10);// this should output// 1, 2, ‘Fizz’, 4, 5, ‘Fizz’, 7, 8, ‘Fizz’, 10

Final step

Since the Fizz condition ran perfectly, let’s apply the same logic to the rest.

// multiple of 5if( (i % 5) === 0 ) {output = ‘Buzz’;}// multiple of 3 and 5if( (i % 3) === 0 && (i % 5 === 0)) {output = ‘FizzBuzz’;}

Wowza!! this satisfies all the conditions and gives us this chef-d’oeuvre of a solution once assembled and stripped out of all comments.

function fizzBuzz( start = 1, end = 100) { 
for( let i = start; i <= end; i++) {
let output = i;
if( (i % 3) === 0 ) {
output = 'Fizz';
}
if( (i % 5) === 0 ) {
output = 'Buzz';
}
if( (i % 3) === 0 && (i % 5) === 0) {
output = 'FizzBuzz';
}
console.log(output);
}
}
fizzBuzz();

Now at this point, I have a working solution that satisfies the challenge request. What follows is very delicate in an interview situation.

Something is bugging me about my code. The last if block that checks for multiples of 3and 5 seems redundant.

Now should I voice that out loud and propose to refactor it or should I wait for the interviewer to call it out?

Interviews are about managing time and maximizing your pluses over your minuses. If you feel super confident that you have a good shot at coming up with something more solid in a manageable time then go for it. If in doubt, wait to be asked.

This way, the interviewer has decided that the remainder of your time might be worth digging deeper on this question.

If it is decided that it would be interesting to look at a refactor, this might be a way to approach the refactor steps

The refactor

We could, of course, get to a fancy one-liner here for this particular challenge, but I’m not a particular fan of doing stuff for the sake of fancy or pretty.

So let’s flip the switch what I’m going to do this time is I will show you my final solution and I will walk you through how did I get to it.

This can turn into a handy skill if you are to read and understand other people’s code or if you are to explain it to someone else.

Through the years I have provided many solutions for this challenge, but the one below is by far my favorite.

function fizzBuzz( start = 1, end = 100) { for( let i = start; i <= end; i++) {  let output = ( (i % 3) ? ‘’ : ‘Fizz’ ); // mult of 3 is falsy  output += ( (i % 5) ? ‘’ : ‘Buzz’) ; // mult of 5 is falsy  console.log(output || i); // output i if output is falsy }}fizzBuzz(1,15);

The solution uses the ternary operator syntax to set the conditions and takes advantage of something that might not very obvious at first for the untrained eye — JavaScript falsy values.

Let’s start with falsy values JavaScript, what in the heck are we talking about. A great definition is provided by the Mozilla Developer Network (MDN ):

A falsy value is a value that is considered false when encountered in a Boolean context.

JavaScript uses Type Conversion to coerce any value to a Boolean in contexts that require it, such as conditionals and loops.

For our particular context, the important keywords are “Boolean context” and “conditionals” since they are relevant to our solution.

Before looking at how it applies, here is the list of the most common falsy values in Javascript:

  • The boolean false not the same as the string ‘false’
  • The number 0 — once again this is different from the string ‘0’
  • The null object
  • The primitive type undefined assigned to a non-initialized variable
  • Any representation of an empty string such as a single quote, double quotes or back-ticks.

The rewrite

Let’s focus on one segment of our fizzBuzz function

if( (i % 3) === 0 ) { output = ‘Fizz’;}// this could be refactored asif( !(i % 3) ) output = ‘Fizz’;

Breaking down the refactored line gives us this picture

  • if (…) ==> conditional construct outside — boolean context inside
  • ! ==> is false
  • (i % 3) ==> type coercion — will check if value is falsy or truthy

Replace i by a few numbers to better understand it

if (!( 1 % 3))/*becomes if (!( 3 )) /*3 is not false or falsy so check fails*/if (!( 2 % 3))/*becomes if (!( 6 )) /*6 is not false or falsy so check fails*/if (!( 3 % 3))/*becomes if (!( 0 )) /*0 is not false but is falsy so check passes*/

I can rewrite now my entire function using the logic above

function fizzBuzz( start = 1, end = 100) { for( let i = start; i <= end; i++) {  let output = i;  if( !(i % 3) ) output = ‘Fizz’;  if( !(i % 5) ) output = ‘Buzz’;  if( !(i % 3) && !(i % 5) ) output = ‘FizzBuzz’;  console.log(output); }}

I was quite ecstatic when I got to this solution, but it did not too long, unfortunately. The last line was still redundant to me and honestly was bugging me. How could I combine the checks of 3 and 5 in one pass?

And then it hit me, what if I could start with an empty string, attach to it the word ‘Fizz’ if it passes the 3 condition and attach the word ‘Buzz’ if it passes the 5 condition too. I drew this on a piece of paper

  • i = 1 ==> no Fizz ‘’ ==> no Buzz ‘’ ==> output is 1
  • i = 3 ==> yes ‘Fizz’ ==> no Buzz ‘’ ==> output is ‘Fizz’
  • i = 5 ==> no Fizz ‘’ ==> yes ‘Buzz’ ==> output is ‘Buzz’
  • i = 15 => yes ‘Fizz’ ==> yes ‘Buzz’ ==> output is ‘FizzBuzz

The ternary operator will allow assigning a value if condition checks and an alternate value if it fails in a very terse manner.

Something else became obvious, we are outputting either a string or a number while we cycling through the values of i and as we saw in a previous section an empty string is a falsy value. So how do we translate all that intelligence into working code?

The essential piece to achieve that was that the value of output was either going to be one of the possible strings ‘Fizz’, ‘Buzz’, ‘FizzBuzz’ or be falsy. In the falsy case i will just be passed as is.

So the final rewrite with more comments

function fizzBuzz( start = 1, end = 100) { for( let i = start; i <= end; i++) {  // output is assigned a value or empty  let output = ( (i % 3) ? ‘’ : ‘Fizz’ );  // output concatenates the next value  output += ( (i % 5) ? ‘’ : ‘Buzz’) ;  // || or operator if output is falsy will show i value  console.log(output || i); }}fizzBuzz(1,15);

Hopefully, you followed all of that :) This was a very satisfying solution to me since I believe it was easy to read, solved the problem and had a touch of eloquent JavaScript in it.

Final words

The coding exercise covers only one aspect of the many things that happen during the coding interview.

As I mentioned the steps and being able to deliver, regardless of the complexity of the problem, take a solid amount of practice.

Don’t hesitate to use mock interviews (we will be offering some in Javascript soon but more on that later) to practice the conversational aspect of it.

I hope this was useful, share and live a comment if you please :)

The Startup

Medium's largest active publication, followed by +503K people. Follow to join our community.

Ady Ngom

Written by

Ady Ngom

bet has always been on Javascript | https://adyngom.com

The Startup

Medium's largest active publication, followed by +503K people. Follow to join our community.

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade