7 Lines to Code Fizz-Buzz Game Principle in Elixir

Blackode
Blackode
Feb 8, 2018 · 8 min read

Coding FizzBuzz Game Backend Principles

This article is all about coding the implicit conditions in FizzBuzz. This makes you to walk over lines of code that gives similar output with different syntax.

To whom ?

This is for complete beginners in Elixir. But, this gonna be more informative at the end.

What is Fizz-Buzz ?

When you google, you will find the following phrases about the FizzBuzz.

FizzBuzz is a very simple programming task, used in software developer job interviews, to determine whether the job candidate can actually write code.

Fizz buzz is a group word game for children to teach them about division. Players take turns to count incrementally, replacing any number divisible by three with the word “fizz”, and any number divisible by five with the word “buzz” and if divisible by both three and five with the word FizzBuzz or else just printing the number itself.

That’s all about the FizzBuzz. Oh.. you finally know what FizzBuzz is . Keep Rocking…

What are we gonna code here?

We simply print the numbers in a range replacing them with words Fizz, Buzz, and FizzBuzz using game protocol.

Fizz-Buzz Timeline

Time to code…

Fizz Section

Here, I named the module with of course everybody does the same and wrote a function.

At first we just print the numbers in the range and see how it works.

defmodule FizzBuzz do
def play(min, max) do
Enum.each(min..max, fn(num)-> IO.puts num end )
end
end

play/2

This function takes two numbers as input technically minimum and maximum values in a range. So, we can create a range via macro.

min..max

A range is represented internally as a struct. A range implements the protocol, which means functions in the module can be used to work with ranges.

You can check the implemented protocols with the help of

i 1..2
i 1..2

So, we took the help of function in the module to iterate a function over the range and printing the numbers.

fn(num) -> IO.puts num end

Here, we used the anonymous function to print the numbers by calling inside the function.

Pattern Matching over function input values

Here, we will write another function with the same name but, this time it takes only single input . According to OOP it is called as Method Overloading.

This is how the code looks.

defmodule FizzBuzz do
def play(min, max) do
Enum.each(min..max, fn(num)-> play(num) end )
end
def play(num) when rem(num, 3) == 0 do
IO.puts "Fizz"
end
end

Changes:

Instead of calling the inside the anonymous function, we created a function for printing. Here, inside the function definition of , we took the help of Elixir guard clause to meet the game conditions.

If the number is divisible by three, the remainder will be . So, we are using the function to get the remainder and to check the truth value of the expression. If the truth value is , it runs the function definition otherwise it won’t run the definition.

Now copy the code and paste it inside the . It compiles well.

Now, call the play function as

iex> FizzBuzz.play 1,20

You will see the run time error. It compiled well but, we got an error at run time.

This is how the error looks.

Trouble Shooting

What’s wrong with our code ?

The first value in the range will be because, ranges are always inclusive.

The first iteration of function call will look like

Enum.each -- fn(1)-> play(1) end

Here, function is triggered with a value but, the guard clause expression would results to So, the function clause is not matched with the passed value.

So, we need to write another function to take charge of printing numbers that don’t divisible by 3 and this is how the code looks.

defmodule FizzBuzz do  def play(min, max) do 
Enum.each(min..max, fn(num)-> play(num) end )
end
def play(num) when rem(num, 3) == 0 do
IO.puts "Fizz"
end
def play(num) do
IO.puts num
end
end

Now give a try by copy pasting above lines of code inside and call the play function as .

You will see the numbers divisible by three iterations will print instead of printing number.

Buzz Section

Like Fizz, we have to add another function function with guard clause checking for divisibility with 5.

Lets see the updated code

defmodule FizzBuzz do  def play(min, max) do 
Enum.each(min..max, fn(num)-> play(num) end )
end
def play(num) when rem(num, 3) == 0 do
IO.puts "Fizz"
end
def play(num) when rem(num, 5) == 0 do
IO.puts "Buzz"
end
def play(num) do
IO.puts num
end
end

FizzBuzz Section

Like Fizz and Buzz we can check the number divisibility by 3 and 5 considering LCM (least common multiple ) of both numbers. The LCM of 3 and 5 is 15. So, if number is divisible by 15, then it is divisible by both 3 and 5.

Let’s add another function.

defmodule FizzBuzz do  def play(min, max) do 
Enum.each(min..max, fn(num)-> play(num) end )
end
def play(num) when rem(num, 3) == 0 do
IO.puts "Fizz"
end
def play(num) when rem(num, 5) == 0 do
IO.puts "Buzz"
end
def play(num) when rem(num, 15) == 0 do
IO.puts "FizzBuzz"
end
def play(num) do
IO.puts num
end
end

Now copy and paste above lines of code and run the function.

To our surprise, it prints the Fizz instead of FizzBuzz at iteration 15.

What’s wrong with our code ?

Trouble Shooting

defmodule FizzBuzz dodef play(min, max) do 
Enum.each(min..max, fn(num)-> play(num) end )
end
def play(num) when rem(num, 3) == 0 do
IO.puts "Fizz"
end
def play(num) when rem(num, 5) == 0 do
IO.puts "Buzz"
end
def play(num) when rem(num, 15) == 0 do
IO.puts "FizzBuzz"
end
def play(num) do
IO.puts num
end
end

Let’s interpret the code at 15 iteration

Enum.each -- #15play(15)
--
play(15) when rem(15, 3) == 0 do

The expression would results to . So, it is just printing the and jumping to next iteration.

So, we need to re order our functions. The function with a guard clause should be above the all the remaining functions. So, it first checks the divisibility with 15 then with 3 and then with 5.

Let’s update the code.

defmodule FizzBuzz dodef play(min, max) do 
Enum.each(min..max, fn(num)-> play(num) end )
end
def play(num) when rem(num, 15) == 0 do
IO.puts "FizzBuzz"
end
def play(num) when rem(num, 3) == 0 do
IO.puts "Fizz"
end
def play(num) when rem(num, 5) == 0 do
IO.puts "Buzz"
end
def play(num) when rem(num, 15) == 0 do
IO.puts "FizzBuzz"
end
def play(num) do
IO.puts num
end
end

Now copy and paste above lines of code in and run the function.

Hurray! We finished the code logic.

But, the title of the article says we need to do that in seven (7) lines of code.

Let’s improve our code.

What else we can improve ?

Instead of copy pasting into every time, we can create a file and paste the code into it.

file fizz_buzz.ex

Now run the command

iex fizz_buzz.ex

You have to be in the same directory of where the file exists.

Otherwise you have to run the command as

iex path/to/file/fizz_buzz.ex

It loads the module into your new session. You can still check the whether the module is loaded with

The changes in the file , can be recompiled with . Here recompiles and reloads the given module.

Code Improvement.

So far, our code consists of 20 lines after deleting empty new lines.

Now we have to improve our code to look much better than before.

Replacements

In elixir, we can replace anonymous function with

So update the line

to

Save the file and recompile it with

We can make this more simple by just passing the name of the function with arity to iterate over the range in

So, update line

Enum.each(min..max, &(play(&1)))

to

Enum.each(min..max, &play/1)

Now save the file with updates then recompile and test it. It still works.

Single Line Functions in Elixir

If you clearly observe the code logic, most of our function definitions are one line. So, we can avoid the blocks. We can update our function definitions with single line style.

#before
def play(num) when rem(num, 15) == 0 do
IO.puts "FizzBuzz"
end
#after updatingdef play(num, 3) when rem(num, 3) == 0, do: IO.puts "FizzBuzz"

Similarly, we will update the remaining function definitions with single line style code base.

This is how it looks after updating

defmodule FizzBuzz do
def play(min, max), do: Enum.each(min..max, &play/1)
def play(num) when rem(num, 15) == 0, do: IO.puts "FizzBuzz"
def play(num) when rem(num, 3) == 0, do: IO.puts "Fizz"
def play(num) when rem(num, 5) == 0, do: IO.puts "Buzz"
def play(num), do: IO.puts num
end

Boom! We developed code logic in 7 lines. That was awesome of you…

This article originally posted at Ahamtech Blog

Happy Coding…

if worth_clapping, do: “clap”, else: nil

blackode

Coding, thoughts, and ideas.

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

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store