 # Let's Solve The FizzBuzz Challenge in Swift

Written by LearnAppMaking on August 5 2020 in App Development, Play With Code, Swift FizzBuzz is a legendary coding challenge. You simply must give it a try! But… what approaches can you use to solve FizzBuzz with the Swift programming language?

In this tutorial, we’re going to solve the FizzBuzz challenge in three different ways:

1. With conditionals
2. With the `switch` statement
3. With `.map()`

A while ago I did a live screencast, where I walk you through FizzBuzz. You can watch it here.

## What is FizzBuzz?

FizzBuzz is a coding challenge. Its instructions are:

• Write a program that prints the numbers from 1 to 100
• For numbers divisible by 3, print “Fizz”
• For numbers divisible by 5, print “Buzz”
• For numbers divisible by both 3 and 5, print “FizzBuzz”

The point of FizzBuzz is to “test” if a person knows how to code. It’s commonly used in coding interviews to test the problem-solving and coding skills of a candidate.

What’s so interesting about FizzBuzz is that its solution is counter-intuitive, and can’t be solved elegantly or efficiently. This often confuses beginner programmers, which makes it an interesting challenge.

As you’ll see in the next section, FizzBuzz can’t be solved with a simple if-this-then-that approach. You’ll have to duplicate some of your code, which will make you second-guess your solution if you wanted to make your code as elegant as possible.

Let’s have a look then, shall we?

Fun Fact: No employer or client has ever asked me to solve FizzBuzz in a coding interview. They did ask me, however, to sort giraffes in groups of ascending heights. The differences in heights in a group couldn’t exceed `1`, because that would make the giraffes insecure… I’ve included a few brain-tickling coding challenges at the end of this tutorial.

## Solving FizzBuzz with Conditionals

We’re now going to write the most basic solution for FizzBuzz, step-by-step. The first step is of course, a for loop:

``````for i in 1...100
{
print(i)
}
``````

The above for loop will loop over the range `1...100` and print out its individual numbers. So far so good!

The next step is to find out if a number is divisible by 3. Here’s how:

``````for i in 1...100
{
if i % 3 == 0 {
print("Fizz")
} else {
print(i)
}
}
``````

That results in the output:

``````1, 2, Fizz, 4, 5, Fizz, 7, 8, Fizz, 10, 11, Fizz
``````

As expected, the numbers 3, 6, 9, 12, etc. are replaced by “Fizz”. Any other number is simply printed out as-is. So, how does that work?

The expression `i % 3 == 0` uses the modulo operator `%` to find the remainder of a division. It divides `i` by 3 and sees if there’s something “left”. For instance, 5 divided by 3 has 2 remaining, i.e. `5 % 3 = 2`. When the remainder is `0` you know for certain that `i` is divisible by 3.

The result of the `i % 3 == 0` expression is a boolean, so you can use it in an if-statement (also called a conditional). When the expression is `true`, “Fizz” is printed. When it’s `false`, the `else` block is executed and the number `i` is printed.

Instead of the modulo operator `%`, you can also use `i.isMultiple(of: 3)` in Swift. This is clearer but more verbose.

Now, let’s extend the code to also test for divisibility by 5. Like this:

``````for i in 1...100
{
if i % 3 == 0 {
print("Fizz")
} else if i % 5 == 0 {
print("Buzz")
} else {
print(i)
}
}
``````

Its output is:

``````1, 2, Fizz, 4, Buzz, Fizz, 7, 8, Fizz, Buzz, 11
``````

As expected, the numbers 5 and 10 are replaced with “Buzz”. The `else if` block checks that `i % 5 == 0` is `true`, and prints out “Buzz”.

Why doesn’t it print “FizzBuzz” too at this point? Because the `if`, `else if` and `else` blocks are evaluated one by one, from top to bottom. When one expression is `true`, the expressions below it aren’t executed. So, when `i` is divisible by 3, the first block executes, and the other block do not.

So… how can you incorporate “FizzBuzz” at this point? That’s what the whole challenge is about! You have two options:

1. You add another `if i % 5 == 0` conditional inside the first `i % 3` conditional. After all, you’re checking that `i` is divisible by both 3 and 5.
2. You add a top-level `if i % 3 == 0 && i % 5 == 0` to the code. This way you’re evaluating the value `i` twice.

Let’s look at the first approach. It goes like this:

``````for i in 1...100
{
if i % 3 == 0 {
if i % 5 == 0 {
print("FizzBuzz")
} else {
print("Fizz")
}
} else if i % 5 == 0 {
print("Buzz")
} else {
print(i)
}
}
``````

Do you see that nested if-statement inside the first `i % 3 == 0` block? It works like this:

• Check if `i` is divisible by 3, and if that’s `true`:
• Check if `i` is divisible by 5, and if that’s `true`, print “FizzBuzz”
• If that’s not `true`, in `else`, print “Fizz”
• (The other conditionals still work the same.)

This code is pretty hard to read. You can’t immediately assess the behavior of every conditional, and you can’t shake the inelegance of executing `i % 5` twice.

Can we use a different approach? Yes! Have a look:

Much better, right? We’re still executing some code twice, but at least it’s readable. You can see at a glance that we’re checking if `i` is divisible by both 3 and 5, or just by one of them, or else.

However, this solution still executes both `i % 3 == 0` and `i % 5 == 0` twice, at worst. The code first evaluates `i % 3 == 0 && i % 5 == 0`, and then those divisions individually.

A most efficient value of `i` here is `15`, for example, because that hits the first conditional immediately. A most inefficient value is one you can’t divide by 3 or 5, like 7, so you have to execute every conditional before ending up at `else`.

## Solving FizzBuzz with Switch and Pattern Matching

The Swift programming language has a very cool feature called pattern matching. We can use it with the switch statement to match its different values with different `switch` cases.

Let’s have a look:

The code is similar to what we had before. We’re looping over `1...100` and printing “Fizz”, “Buzz”, “FizzBuzz” or a number for every iteration of the loop.

Instead of an `if` statement, we’re using `switch`. In short, a `switch` statement takes one expression, and has a number of `case` blocks for every possible value of that expression.

In the above code, we’re constructing a tuple out of the expression `(i % 3 == 0, i % 5 == 0)`. A tuple combines two values in an ordered list. Because both values in the tuple can be `true` or `false`, the full tuple now has 4 different values:

``````(true, true)
(false, false)
(true, false)
(false, true)
``````

In the `switch` statement we can now match those tuples to different `case` blocks. Here, walk through this list on your own:

• `(true, false)` means that `i` is only divisible by 3
• `(false, true)` means that `i` is only divisible by 5
• `(true, true)` means that `i` is divisible by both 3 and 5
• `(false, false)` means that `i` isn’t divisible by neither 3 nor 5

In code, that looks like this:

``````switch (i % 3 == 0, i % 5 == 0)
{
case (true, false):
print("Fizz")
case (false, true):
print("Buzz")
case (true, true):
print("FizzBuzz")
default:
print(i)
}
``````

See how the expressions `i % 3 == 0` and `i % 5 == 0` are assessed, and its values matched to different `case` blocks? Note that the `default` block matches anything that the other blocks don’t match.

You know what’s so cool about the above code? The `(i % 3 == 0, i % 5 == 0)` expression is evaluated once for every iteration of `i`. Unlike the previous example, with the `if` statements, the code that evaluates if `i` is divisible only runs once. Albeit for every iteration of `i`, but that’s still better than twice for every iteration of `i`.

Note: The `switch` statement in Swift has no implicit fall-through, unlike other programming languages. You won’t have to explicitly `break` a `case`. When you want a `case` to fall-through, use `fallthrough` explicitly.

Just for fun, let’s look at another way of solving FizzBuzz that’s identical to the one with `switch`, but syntactically different. Check this out:

``````let FIZZ = true
let BUZZ = true

for i in 1...100
{
switch (i % 3 == 0, i % 5 == 0)
{
case (FIZZ, BUZZ):
print("FizzBuzz")
case (FIZZ, _):
print("Fizz")
case (_, BUZZ):
print("Buzz")
default:
print(i)
}
}
``````

What’s going on here? We’ve changed a few things:

• At the top of the code we’ve defined constants `FIZZ` and `BUZZ`, both set to `true`. They’re going to serve as “aliases” for the Fizz, Buzz and FizzBuzz numbers in the range from 1 to 100.
• Instead of pattern matching with `true` and `false`, we’re now using the constants (“aliases”) `FIZZ` and `BUZZ` for `true` in `case`. We’ve changed `false` in an underscore `_`, so we’re ignoring those `false` values.
• The order of cases in `switch` has changed. We’ll need to make sure that the pattern for FizzBuzz matches first. If we hadn’t, the “Fizz” case would also match for “FizzBuzz” because we’re ignoring the `false` value matches.

Even though the way the code works is still the same, it’s syntactically different. We’re using the `FIZZ` and `BUZZ` constants to obscure the pattern matching in `case`, which makes the code more expressive. Neat!

Big thanks for this approach to Tim “Mr. C” Colson.

## Solving FizzBuzz with “map(_:)”

The previous examples all printed out values to the Console, but what if you want to evaluate a range of FizzBuzz as a whole?

Let’s spice up FizzBuzz! Just because we can. It’s about playing with code, right?

First, we’re going to put FizzBuzz into a closure. Like this:

``````let fizzbuzz:(Int) -> String = { i in
switch (i % 3 == 0, i % 5 == 0)
{
case (true, false):
return "Fizz"
case (false, true):
return "Buzz"
case (true, true):
return "FizzBuzz"
default:
return "\(i)"
}
}
``````

The code is similar to what you’ve seen before. Instead right now, we can call `fizzbuzz()` for any arbitrary value and get the right string back.

``````fizzbuzz(15)
// Output: FizzBuzz

fizzbuzz(3)
// Output: Fizz
``````

And then here’s a beautiful one-liner:

``````Array(1...100).map(fizzbuzz).joined(separator: ", ")
``````

Whaaat? How does it work? It’s simple:

1. Create an array with integer values from `1` to `100`
2. Call map(_:) on that array, calling the closure `fizzbuzz` for every item in the array, mapping integer values to string values
3. Calling `joined(separator:)` on the resulting array of strings, effectively glueing them together with commas

The result:

1, 2, Fizz, 4, Buzz, Fizz, 7, 8, Fizz, Buzz, 11, Fizz, 13, 14, FizzBuzz, 16, 17, … FizzBuzz, 91, 92, Fizz, 94, Buzz, Fizz, 97, 98, Fizz, Buzz

Awesome!

FizzBuzz is a terrific primer for coding interview challenges. It helps you to think strategically instead of intuitively, and to assess every different scenario and edge case that can occur in your code. And it’s a whole lot of fun!

Looking for more fun Swift challenges? Check these out: