How To Never Fail At The Fizzbuzz Interview Challenge
Tags: kotlin, beginners, career, tutorial
Published: 2017-10-11 20:11:32

---
title: How To Never Fail At The Fizzbuzz Interview Challenge
published: true
description: Do you know that you don’t have even a single excuse to fail at one of these? So you think that you know that coding kata well? What if I told you there are additional requirements that the interviewer can throw at you? Check this solution for FizzBuzz challenge in Kotlin and some nasty unexpected requirements!.
cover_image: https://thepracticaldev.s3.amazonaws.com/i/1bj0tf56owcaa2gcmx0u.png
tags: 
- kotlin
- beginners
- career
- tutorial
---

Ah, the classic FizzBuzz coding challenge.

I’ve decided to include this picture to get your attention. Oh, and also because it associates with the “Buzz” part of the challenge.

“Buzz” – alarm clock…

Onward! Do you know that you don’t have even a single excuse to fail at one of these? So you think that you know that coding kata well?

Let your imagination run wild:

You are at the coding interview, and the interviewer has just asked you to implement FizzBuzz and given you the following problem description:


> Write a program that prints a sequence of numbers from 1 to N.
>
> Every number that divides by the three should appear as “Fizz.”
>
> Every number that divides by the five should appear as “Buzz.”
>
> Every number that divides by the three and the five should appear as “FizzBuzz.”
>
> – anonymous interviewer

A piece of cake!

So you are writing away, and the code is pouring out of you…

Five or ten minutes in and you are done. You feel the interviewer might just suspect that you were ready for the challenge. In that case, they will have some additional unexpected requirements for you.

Just like in the real world programming.

Continue reading, and we will explore these additional requirements and possible solution for them. And for now, we will solve the FizzBuzz challenge in Kotlin.

It is probably a good idea to have some automated tests so that we know when we are done. Let’s create a new test suite in JUnit4:

```kotlin
import org.junit.Assert.*
import org.junit.Test

@Suppress("FunctionName")
class FizzBuzzTest {

}
```

Now we are going to write a first test – the simplest one, that covers the fact that we can produce a normal number sequence without any “fizzes” or “buzzes”:

```kotlin
@Test
fun `simple numbers`() {
    // ARRANGE
    val fizzBuzz = FizzBuzz()

    // ACT
    val sequence = fizzBuzz.generateSequence(size = 2)

    // ASSERT
    assertEquals(listOf("1", "2"), sequence)
}
```

I like to split my tests in three sections: arrange, act and assert. It is not necessary to write out loud these comments as I do here. I don’t usually do myself so, but I think about these three sections when constructing a good test.

On the other hand, I highly recommend you DO split your tests in such three sections. And write down these comments too for the sake of explicitness.

If you are already comfortable writing great tests, feel free to ignore my advice.

Onward! There are few compile errors in this test that we will need to deal with. First, we haven’t defined `FizzBuzz` class yet. Second, we will need to create the `generateSequence` method.

Just to make things compile, we will make that method return an empty list:

```kotlin
class FizzBuzz {
    
    fun generateSequence(size: Int): List<String> {
        return emptyList()
    }

}
```

Now we can run our test. As expected, it fails because we are expecting a list with two items `["1", "2"]`, but we are getting an empty list `[]`.

Making this pass is pretty simple. We are going to generate a sequence from one to `size` using Kotlin’s range syntax:

```kotlin
1..size
```

Then we are going to generate a new sequence out of it by calling `toString()` method on every item of that sequence. To do that we are going to employ `map` function defined on any Kotlin sequence:

```kotlin
fun generateSequence(size: Int): List<String> {
    return (1..size).map { it.toString() }
}
```

Oh, by the way.

Wondering what all these neat features of Kotlin are? Maybe you want to learn how to build a full-fledged application in Kotlin?

I have accidentally written this 80-page hands-on getting started tutorial for Kotlin. Feel welcome to [download the free PDF Ultimate Tutorial: Getting Started With Kotlin](https://iwillteachyoukotlin.com). You are going to learn how to build a full-fledged command-line application in Kotlin. You’ll get free access preview for Web app and Android app tutorials, as well!

Anyways, we should run our tests now.

And they all pass.

Alright. Our next step is to start handling some “fizz” numbers. For that, we can write a new test. It is as simple as copy-pasting (oh no!) the previous test and making some modifications to it:

```kotlin
@Test
fun `fizz numbers`() {
    // ARRANGE
    val fizzBuzz = FizzBuzz()

    // ACT
    val sequence = fizzBuzz.generateSequence(size = 4)

    // ASSERT
    assertEquals(listOf("1", "2", "Fizz", "4"), sequence)
}
```

Now we are going from one to four, and we are expecting all numbers to be normal except for number three. It should become “Fizz” in the generated sequence.

If we run this test, it is going to fail, because so far we are producing only simple numbers converted to strings.

To make this test pass we are going to extract `it.toString()` part into a private method `generateMethod(number: Int): String`. We will add an “if” statement to handle the case when the number divides by three:

```kotlin
fun generateSequence(size: Int): List<String> {
    return (1..size).map { generateNumber(it) }
}

private fun generateNumber(number: Int): String {
    if (number % 3 == 0) {
        return "Fizz"
    }

    return number.toString()
}
```

It passes the test suite now.

Next, we would like to write a test for the “Buzz” requirement. For that, we are going to generate a sequence from one to fourteen. There will be a few “fizzes” and “buzzes” there.

No “fizzbuzzes” yet, though.

```kotlin
@Test
fun `buzz numbers`() {
    // ARRANGE
    val fizzBuzz = FizzBuzz()

    // ACT
    val sequence = fizzBuzz.generateSequence(size = 14)

    // ASSERT
    assertEquals(listOf(
            "1", "2", "Fizz", "4", "Buzz",
            "Fizz", "7", "8", "Fizz", "Buzz",
            "11", "Fizz", "13", "14"), sequence)
}
```

That test fails because we are not producing any “buzzes” yet. We will add another “if” statement to handle that case:

```kotlin
private fun generateNumber(number: Int): String {
    if (number % 3 == 0) {
        return "Fizz"
    }

    if (number % 5 == 0) {
        return "Buzz"
    }

    return number.toString()
}
```

And the test is passing.

Finally, we want to write a test involving some “fizzbuzzy” numbers. In this case, we want to generate a sequence from one to thirty-one, so that we include at least two of these:

```kotlin
@Test
fun `fizz buzz numbers`() {
    // ARRANGE
    val fizzBuzz = FizzBuzz()

    // ACT
    val sequence = fizzBuzz.generateSequence(size = 31)

    // ASSERT
    assertEquals(listOf(
            "1", "2", "Fizz", "4", "Buzz",
            "Fizz", "7", "8", "Fizz", "Buzz",
            "11", "Fizz", "13", "14", "FizzBuzz",
            "16", "17", "Fizz", "19", "Buzz",
            "Fizz", "22", "23", "Fizz", "Buzz",
            "26", "Fizz", "28", "29", "FizzBuzz",
            "31"), sequence)
}
```

And of course it does not work.

That is because the first “if” statement (for “fizzes”) catches this case and produces “Fizz.” To fix that we will have to write a new “if” statement that handles the case for “fizzes” and “buzzes” at the same time.

That case will have to be checked before all others. That way, nor “Fizz,” nor “Buzz,” will match before it:

```kotlin
private fun generateNumber(number: Int): String {
    if (number % 3 == 0 && number % 5 == 0) {
        return "FizzBuzz"
    }

    if (number % 3 == 0) {
        return "Fizz"
    }

    if (number % 5 == 0) {
        return "Buzz"
    }

    return number.toString()
}
```

Alrighty! All tests are passing now.

Let’s extract some duplication in the test suite. Notably, the `ARRANGE` part. That is because it is the same for every single test. We will promote `fizzBuzz` local variable to the private field of the test suite class:

```kotlin
import org.junit.Assert.*
import org.junit.Test

@Suppress("FunctionName")
class FizzBuzzTest {

    private val fizzBuzz = FizzBuzz()

    @Test
    fun `simple numbers`() {
        // ACT
        val sequence = fizzBuzz.generateSequence(size = 2)

        // ASSERT
        assertEquals(listOf("1", "2"), sequence)
    }

    @Test
    fun `fizz numbers`() {
        // ACT
        val sequence = fizzBuzz.generateSequence(size = 4)

        // ASSERT
        assertEquals(listOf("1", "2", "Fizz", "4"), sequence)
    }

    @Test
    fun `buzz numbers`() {
        // ACT
        val sequence = fizzBuzz.generateSequence(size = 14)

        // ASSERT
        assertEquals(listOf(
                "1", "2", "Fizz", "4", "Buzz",
                "Fizz", "7", "8", "Fizz", "Buzz",
                "11", "Fizz", "13", "14"), sequence)
    }

    @Test
    fun `fizz buzz numbers`() {
        // ACT
        val sequence = fizzBuzz.generateSequence(size = 31)

        // ASSERT
        assertEquals(listOf(
                "1", "2", "Fizz", "4", "Buzz",
                "Fizz", "7", "8", "Fizz", "Buzz",
                "11", "Fizz", "13", "14", "FizzBuzz",
                "16", "17", "Fizz", "19", "Buzz",
                "Fizz", "22", "23", "Fizz", "Buzz",
                "26", "Fizz", "28", "29", "FizzBuzz",
                "31"), sequence)
    }

}
```

If we run the tests, they should still pass. As our next step, we should take a careful look if there is any duplication in the production code.

And there is some!

The checks for “fizziness” and “buzziness” are duplicated between “fizzbuzz” case handler and corresponding “fizz” or “buzz” case handler. Simplest refactoring we can do is to extract these into private functions:

```kotlin
private fun generateNumber(number: Int): String {
    if (isFizz(number) && isBuzz(number)) {
        return "FizzBuzz"
    }

    if (isFizz(number)) {
        return "Fizz"
    }

    if (isBuzz(number)) {
        return "Buzz"
    }

    return number.toString()
}

private fun isBuzz(number: Int) = number % 5 == 0

private fun isFizz(number: Int) = number % 3 == 0
```

At that point, you were about to refactor some more, for example, extract magic strings to constants.

But the interviewer told you it is enough refactoring.

You see they are impressed. You have finished earlier after all. But you feel as if the interviewer is a little bit suspicious. It is a classic exercise after all.

So they decide to give you an additional requirement!

> A number should also be “Fizz” if it contains digit “3.”
>
> A number should also be “Buzz” if it contains digit “5.”
>
> A number should also be “FizzBuzz” if it contains both.
>
> – anonymous interviewer

Oh, no!

Nobody told you there could be more…

Don’t fret! We are going to go through that. Let’s add a new test for the “Fizz” part with the new requirement.

We are going to generate the sequence until 32. Some numbers, which weren’t “Fizz” before, will become such:

```kotlin
@Test
fun `fizz numbers that just contain digit '3'`() {
    // ACT
    val sequence = fizzBuzz.generateSequence(size = 32)

    // 13 becomes Fizz
    // 23 becomes Fizz
    // 31 becomes Fizz
    // 32 becomes Fizz

    // ASSERT
    assertEquals(listOf(
            "1", "2", "Fizz", "4", "Buzz",
            "Fizz", "7", "8", "Fizz", "Buzz",
            "11", "Fizz", "Fizz", "14", "FizzBuzz",
            "16", "17", "Fizz", "19", "Buzz",
            "Fizz", "22", "Fizz", "Fizz", "Buzz",
            "26", "Fizz", "28", "29", "FizzBuzz",
            "Fizz", "Fizz"), sequence)
}
```

Of course, the test is failing.

To make it pass we will need to modify the function `isFizz` appropriately. You should include the check for “it contains digit 3” on top of the original condition. In boolean logic (last time I checked) it was an “OR” operation between those two conditions:

```kotlin
private fun isFizz(number: Int) =
        number % 3 == 0 || number.toString().contains('3')
```

Note the `number.toString().contains('3')` part. The test is passing now. But a few of other tests are failing!

Oh no!

We will have to fix those tests. We should replace numbers containing digit “3” with “Fizz”:


```kotlin
@Test
fun `buzz numbers`() {
    // ACT
    val sequence = fizzBuzz.generateSequence(size = 14)

    // ASSERT
    assertEquals(listOf(
            "1", "2", "Fizz", "4", "Buzz",
            "Fizz", "7", "8", "Fizz", "Buzz",
            "11", "Fizz", "Fizz", "14"), sequence)
}
```

```kotlin
@Test
fun `fizz buzz numbers`() {
    // ACT
    val sequence = fizzBuzz.generateSequence(size = 31)

    // ASSERT
    assertEquals(listOf(
            "1", "2", "Fizz", "4", "Buzz",
            "Fizz", "7", "8", "Fizz", "Buzz",
            "11", "Fizz", "Fizz", "14", "FizzBuzz",
            "16", "17", "Fizz", "19", "Buzz",
            "Fizz", "22", "Fizz", "Fizz", "Buzz",
            "26", "Fizz", "28", "29", "FizzBuzz",
            "Fizz"), sequence)
}
```

Hold on a second… Doesn’t this feel weird to you?

Yeah, I think this last case covers all our edge cases. That is because it (kind of) includes all other tests. So you should get rid of those tests!

Oh, and don’t forget to demote the private field `fizzBuzz` back to the local variable.

Here we go:

```kotlin
import org.junit.Assert.*
import org.junit.Test

@Suppress("FunctionName")
class FizzBuzzTest {

    @Test
    fun `generating fizz buzz sequence`() {
        // ARRANGE
        val fizzBuzz = FizzBuzz()

        // ACT
        val sequence = fizzBuzz.generateSequence(size = 32)

        // ASSERT
        assertEquals(listOf(
                "1", "2", "Fizz", "4", "Buzz",
                "Fizz", "7", "8", "Fizz", "Buzz",
                "11", "Fizz", "Fizz", "14", "FizzBuzz",
                "16", "17", "Fizz", "19", "Buzz",
                "Fizz", "22", "Fizz", "Fizz", "Buzz",
                "26", "Fizz", "28", "29", "FizzBuzz",
                "Fizz", "Fizz"), sequence)
    }

}
```

Now we want to implement final two requirements.

For that let’s change our test to go until `53`, so we hit more attractive edge cases. And some of the numbers will become “Buzz” and some other numbers ought to become “FizzBuzz” now.

See for yourself:

```kotlin
@Test
fun `generating fizz buzz sequence`() {
    // ARRANGE
    val fizzBuzz = FizzBuzz()

    // ACT
    val sequence = fizzBuzz.generateSequence(size = 53)

    // 35 became FizzBuzz
    // 51 became FizzBuzz
    // 52 became Buzz
    // 53 became FizzBuzz

    // ASSERT
    assertEquals(listOf(
            "1", "2", "Fizz", "4", "Buzz",
            "Fizz", "7", "8", "Fizz", "Buzz",
            "11", "Fizz", "Fizz", "14", "FizzBuzz",
            "16", "17", "Fizz", "19", "Buzz",
            "Fizz", "22", "Fizz", "Fizz", "Buzz",
            "26", "Fizz", "28", "29", "FizzBuzz",
            "Fizz", "Fizz", "Fizz", "Fizz", "FizzBuzz",
            "Fizz", "Fizz", "Fizz", "Fizz", "Buzz",
            "41", "Fizz", "Fizz", "44", "FizzBuzz",
            "46", "47", "Fizz", "49", "Buzz",
            "FizzBuzz", "Buzz", "FizzBuzz"), sequence)
}
```

To make this pass, we will need to add similar condition to the `isBuzz` private function. Notice the `number.toString().contains('5')` part.

```kotlin
private fun isBuzz(number: Int) =
        number % 5 == 0 || number.toString().contains('5')
```

The tests are back to green now (they pass).

Don’t you notice how `isBuzz` and `isFizz` functions have a similar structure? Don’t you think we should be able to extract that structure?

Let’s do it!

First, we will extract `dividesBy(number, divider)` private function:

```kotlin
private fun isBuzz(number: Int) =
        dividesBy(number, 5) || number.toString().contains('5')

private fun isFizz(number: Int) =
        dividesBy(number, 3) || number.toString().contains('3')

private fun dividesBy(number: Int, divider: Int) =
        number % divider == 0
```

Second, we will extract `containsDigit(number, digit)` private function.

```kotlin
private fun isBuzz(number: Int) =
        dividesBy(number, 5) || containsDigit(number, 5)

private fun isFizz(number: Int) =
        dividesBy(number, 3) || containsDigit(number, 3)

private fun containsDigit(number: Int, digit: Int) =
        number.toString().contains(digit.toString())
```

Note how `digit` here is not a character or string. It is an integer.

That way, we should be able to extract the whole structure (`dividesBy` or `containsDigit`) out of those two functions.

Here we go:

```kotlin
private fun isBuzz(number: Int) =
        dividesOrContainsDigit(number, 5)

private fun isFizz(number: Int) =
        dividesOrContainsDigit(number, 3)

private fun dividesOrContainsDigit(number: Int, digit: Int) =
        dividesBy(number, digit) || containsDigit(number, digit)
```

Your interviewer is not stopping your refactoring yet. So maybe he is out of requirements?

Thank goodness!

Finally, you can do that magic strings extraction refactoring! For that, we will extract “Fizz” and “Buzz” strings out of respective edge cases. And from the “fizzbuzzy” one too:

```kotlin
companion object {
    private val FIZZ = "Fizz"
    private val BUZZ = "Buzz"
    private val FIZZ_BUZZ = "$FIZZ$BUZZ"
}

private fun generateNumber(number: Int): String {
    if (isFizz(number) && isBuzz(number)) {
        return FIZZ_BUZZ
    }

    if (isFizz(number)) {
        return FIZZ
    }

    if (isBuzz(number)) {
        return BUZZ
    }

    return number.toString()
}
```

So why are we extracting these magic strings, anyway?

You might ask that yourself…

Or is it just the interviewer asking you that question?

Probably, because you want to make it easy to change one of these strings in just one place, don’t you?

And that is where the thought strikes you! What if I need to change “Fizz” to “Fizzy”?

Yep.

I’ll have to fix all these occurrences in the test suite.

Annoying!

Let’s replace all the magic strings in the test too. We will have to promote these private constants `FIZZ`, `BUZZ`, and `FIZZ_BUZZ` to internal access level so that that the test can access them:

```kotlin
companion object {
    internal val FIZZ = "Fizz"
    internal val BUZZ = "Buzz"
    internal val FIZZ_BUZZ = "$FIZZ$BUZZ"
}
```

And finally, we are going to replace the string occurrences in the test suite:

```kotlin
import FizzBuzz.Companion.BUZZ
import FizzBuzz.Companion.FIZZ
import FizzBuzz.Companion.FIZZ_BUZZ
import org.junit.Assert.*
import org.junit.Test

@Suppress("FunctionName")
class FizzBuzzTest {

    @Test
    fun `generating fizz buzz sequence`() {
        // ARRANGE
        val fizzBuzz = FizzBuzz()

        // ACT
        val sequence = fizzBuzz.generateSequence(size = 53)

        // ASSERT
        assertEquals(listOf(
                "1", "2", FIZZ, "4", BUZZ,
                FIZZ, "7", "8", FIZZ, BUZZ,
                "11", FIZZ, FIZZ, "14", FIZZ_BUZZ,
                "16", "17", FIZZ, "19", BUZZ,
                FIZZ, "22", FIZZ, FIZZ, BUZZ,
                "26", FIZZ, "28", "29", FIZZ_BUZZ,
                FIZZ, FIZZ, FIZZ, FIZZ, FIZZ_BUZZ,
                FIZZ, FIZZ, FIZZ, FIZZ, BUZZ,
                "41", FIZZ, FIZZ, "44", FIZZ_BUZZ,
                "46", "47", FIZZ, "49", BUZZ,
                FIZZ_BUZZ, BUZZ, FIZZ_BUZZ), sequence)
    }

}
```

All your tests should be green at this point.

Did you need to do all these refactorings?

Not necessarily.

Do you need to know how to do them, so that you are ready for any requirement change?

Absolutely!

Here is the final production code:

```kotlin
class FizzBuzz {

    companion object {
        internal val FIZZ = "Fizz"
        internal val BUZZ = "Buzz"
        internal val FIZZ_BUZZ = "$FIZZ$BUZZ"
    }

    fun generateSequence(size: Int): List<String> {
        return (1..size).map { generateNumber(it) }
    }

    private fun generateNumber(number: Int): String {
        if (isFizz(number) && isBuzz(number)) {
            return FIZZ_BUZZ
        }

        if (isFizz(number)) {
            return FIZZ
        }

        if (isBuzz(number)) {
            return BUZZ
        }

        return number.toString()
    }

    private fun isBuzz(number: Int) =
            dividesOrContainsDigit(number, 5)

    private fun isFizz(number: Int) =
            dividesOrContainsDigit(number, 3)

    private fun dividesOrContainsDigit(number: Int, digit: Int) =
            dividesBy(number, digit) || containsDigit(number, digit)

    private fun containsDigit(number: Int, digit: Int) =
            number.toString().contains(digit.toString())

    private fun dividesBy(number: Int, divider: Int) =
            number % divider == 0

}
```

I genuinely thank you for reading, and I encourage you to practice your basic foundations.

There are tons of different challenges for that on websites like http://codingdojo.org/kata/ and http://kata-log.rocks. Huge thank you to creators and maintainers!

Liked this article? – Share it with your friends, on social media, hacker news, Reddit, etc. If you are interested in Kotlin, [check out more of my stuff on Kotlin](https://iwillteachyoukotlin.com).