How to Solve FizzBuzz
Using Ruby
FizzBuzz is a pretty common algorithm interview question. It is used to help filter out programmers who and I quote “can’t seem to program their way out of a wet paper bag”. It was created by Imran Ghory, you can read his take on it here. The basic idea is to write a program that prints numbers (1-n), where n is an argument passed in. For multiples of three, you print the word “Fizz”, for multiples of five you print “Buzz. For multiples of both three and five you print “FIzzBuzz”. The return would look like this.
n = 15,
Return:
[
"1",
"2",
"Fizz",
"4",
"Buzz",
"Fizz",
"7",
"8",
"Fizz",
"Buzz",
"11",
"Fizz",
"13",
"14",
"FizzBuzz"
]
It seems like a pretty easy problem. I still remember the first time I saw it. I had just started getting into algorithms practice. This may have been the first or second one I had seen. Which makes sense because it supposed to be a tiny problem. I had no idea what to do. I could pseudo-code it out but didn't really know what to do. I’ve come a little way, I’m definitely getting better. I’m going to go over two different ways to complete the exercise. One will be the brute force or naive way of solving it. Then I will discuss a more DRY(Don’t Repeat Yourself) way of solving.
def fizz_buzz(n)end
So we have a method fizz_buzz which has an argument of (n). The first thing we need to do is iterate over the collection of numbers. We will use the inclusive range operator, which we will then map over.
def fizz_buzz(n) (1..n).map do |num|
end
end
After that, we will create an if statement. This is where we will start testing out numbers. We have to test for multiples three and five first. Otherwise, we won’t make it because three and five separately would fulfill that requirement. The modulo operator divides the left number by the right number and returns a remainder. We know that if no remainder exists then the number is multiple.
def fizz_buzz(n) (1..n).map do |num|
if num % 3 == 0 && num % 5 == 0
"FizzBuzz" end
end
For the next to requirements we basically just split the first one and change the return. To finish the if statement we just return the number if it doesn't meet any of the requirements. Some test sites like Leetcode to Hankerrank might want you to convert the number to a string. In this case, just attached “.to_s” to num.
def fizz_buzz(n) (1..n).map do |num|
if num % 3 == 0 && num % 5 == 0
"FizzBuzz"
elsif num % 3 == 0
"Fizz"
elsif num % 5 == 0
"Buzz"
else
num
end
end
end
That's it, a simple way to solve a fairly simple problem. The problem I had originally is not fully understanding the modulo operator. Once I figured out how that worked, it made it easy to figure out the rest.
DRY(Don’t Repeat Yourself)
Now that you’ve seen the brute force example, let’s see a way that cleans us the code a little. The main thing I want to clean up is how many times I’m using the modulo operator. In the above method, I’m using it four times. That seems a little redundant. Let's see if we can’t clean it up.
With this solution, we lonely have to type out the modulo operator twice and then just pass in the variable. It is much faster than the previous method and much dry. There are a few things we could do to make this even dryer, but I don't want to get carried away.
def fizz_buzz(n)
(1..n).map do |num|
fizz = (num % 3 == 0)
buzz = (num % 5 == 0)
if fizz && buzz
"FizzBuzz"
elsif fizz
"Fizz"
elsif buzz
"Buzz"
else
num
end
end
end
CONCLUSION
FizzBuzz is one of those common problems that is deeply ingrained in programming culture with meme’s abound. It’s a fun problem that can be daunting in the beginning, but once you master it you can move on to more difficult problems. Hopefully, this was helpful. Let me know if you can think of a DRYer way to write the method.