small medium large xlarge

• Rewrite the FizzBuzz example using `case`.

A Possible Solution</summary>

```defmodule FizzBuzz do

def upto(n) when n > 0 do
1..n |> Enum.map(fizzbuzz(&1))
end

defp fizzbuzz(n) do
case { rem(n, 3), rem(n, 5), n } do
{ 0, 0, _ } -> "FizzBuzz"
{ 0, _, _ } -> "Fizz"
{ _, 0, _ } -> "Buzz"
{ _, _, n } -> n
end
end
end
```

</details>

Hi Dave,

First, thank you for a(nother) great book!

I’m wondering why you included `n` in the tuple within `fizzbuzz`. It does not change bindings within the function, so wouldn’t the following be a bit cleaner:

```defmodule FizzBuzz do

def upto(n) when n > 0 do
1..n |> Enum.map(&_fizzbuzz_2/1)
end

defp _fizzbuzz_2(n) do
case { rem(n, 3), rem(n, 5) } do
{ 0, 0 } -> "FizzBuzz"
{ 0, _ } -> "Fizz"
{ _, 0 } -> "Buzz"
_        -> n
end
end

end
```

Update: Is there a (simple) way to hide our code in the forums? I’d prefer not to spoil the exercise for others.

Update 2: Thank you!

I did it simply because it logically felt better to me to pass it in the match, rather than in the closure. I could be swayed either way.

To hide something enclose it in <details markdown=”block”>…</details>

My try at this:

``````defmodule FizzBuzz do
def upto(n) when n > 0 do
1..n |> Enum.map(&fizzbuzz/1)
end

defp fizzbuzz(n) do
test = [rem(n, 3), rem(n, 5)]
case test do
[0, 0] -> "FizzBuzz"
[0, _] -> "Fizz"
[_, 0] -> "Buzz"
_      -> n
end
end
end
``````
``````defmodule FizzBuzz do

def upto(n), do: fizzbuzz(n, [])
def fizzbuzz(0, result), do: result
def fizzbuzz(n, result) do
val = case {rem(n,3), rem(n,5), n} do
{0,0,_} -> "FizzBuzz"
{0,_,_} -> "Fizz"
{_,0,_} -> "Buzz"
{_,_,n} -> n
end
fizzbuzz(n-1, [val | result])
end

end
``````

Since `case` supports function guards, it can be written in the following way, although it renders the case useless (and I wouldn’t recommend it):

``````defmodule FizzBuzz do
def upto(n) do
1..n |> Enum.map(&fizzbuzz/1)
end
defp fizzbuzz(n) do
case n do
n when rem(n,3)==0 and rem(n,5)==0 -> "FizzBuzz"
n when rem(n,3)==0 -> "Fizz"
n when rem(n,5)==0 -> "Buzz"
_ -> n
end
end
end
``````

I know nesting 3 deep is generally bad practice, but it felt off to make function to hold a case statement.

``````defmodule ControlFlow do
def fizzbuzz_case(n) do
for num <- 1..n do
case {num, rem(num, 3), rem(num, 5)} do
{_, 0, 0} ->
"FizzBuzz"
{_, 0, _} ->
"Fizz"
{_, _, 0} ->
"Buzz"
_ ->
num
end
end
end
end
``````

Here’s my take on it:

``````defmodule Exs do
def fizzb(b) do
1..b
|> Enum.map( &(printer(&1)))

end

defp printer(x) do
phrase =
case rem(x, 3) do
0 -> "Fizz"
_ -> ""
end

phrase2 =
case rem(x, 5) do
0 -> "Buzz"
_ -> ""
end

result =
case phrase <> phrase2 do
"" -> to_string(x)
_ -> phrase <> phrase2
end

result
end

end
``````

I should have realized this could have been made a lot shorter, but this gets the job done:

```def upto(n) when n > 0, do: _upto(1, n, [])

defp _upto(current, 0, result), do: Enum.reverse result

defp _upto(current, left, result) do
fizzbuzz = check_fizzbuzz({ rem(current, 3), rem(current, 5) }, current)
_upto(current + 1, left - 1, [ fizzbuzz | result ])
end

def check_fizzbuzz(remainder_tuple, current) do
case remainder_tuple do
{0, 0} ->
"FizzBuzz"
{0, _} ->
"Fizz"
{_, 0} ->
"Buzz"
{_, _} ->
current
end
end
```
```defmodule FizzBuzz do
def upto(n) when n > 0 do
1..n |> Enum.map(&fizzbuzz/1)
end

def fizzbuzz(n) do
case {rem(n, 3), rem(n, 5)} do
{0, 0} -> "FizzBuzz"
{0, _} -> "Fizz"
{_, 0} -> "Buzz"
_ -> n
end
end
end
```
``````
defmodule Fizzu do

def fz(n) when n > 0 do
1..n
|> Enum.map( fn n -> _fz(n) end )
end

defp _fz(n) do

case [rem( n , 3 ),rem( n , 5 )] do
[0,0] -> "FizzBuzz"
[0,_] -> "Fizz"
[_,0]  -> "Buzz"
[_,_] -> n
end

end

end

``````
You must be logged in to comment