# Polyglot Dojo #2: FizzBuzz [2*]

## December 19, 2019

• [2019-12-23 Mon]: Added Rust Solution.

• [2019-12-21 Sat]: Added Clojure Solution.

## Challenge

This challenge was disappointingly dull, however, I saw some exciting things through the way. We are going to solve FizzBuzz, with the following constraints:

1. What is fizz buzz? Return the string representation of numbers from 1 to n

• Multiples of 3 -> 'Fizz'

• Multiples of 5 -> 'Buzz'

• Multiples of 3 and 5 -> 'FizzBuzz'

2. Can we assume the inputs are valid? No

3. Can we assume this fits memory? Yes

And the provided unit test is as this:

from nose.tools import assert_equal, assert_raises

class TestFizzBuzz(object):

def test_fizz_buzz(self):
solution = Solution()
assert_raises(TypeError, solution.fizz_buzz, None)
assert_raises(ValueError, solution.fizz_buzz, 0)
expected = [ '1', '2', 'Fizz', '4', 'Buzz', 'Fizz', '7', '8', 'Fizz',
'Buzz', '11', 'Fizz', '13', '14', 'FizzBuzz' ]
assert_equal(solution.fizz_buzz(15), expected)
print('Success: test_fizz_buzz')

def main():
test = TestFizzBuzz()
test.test_fizz_buzz()

if __name__ == '__main__':
main()

So far, so good, let's start.

## Python Solution

To solve this challenge, we first need to implement a function to take care of a single input (map an input to a single output). The constraints are so straightforward, and we basically need to re-write them in Python:

def is_divisible(number, by):
if by == 0:
raise ValueError("Expects non-zero denominator")

return number % by == 0

def process_number(number):
if is_divisible(number, 3) and is_divisible(number, 5):
return "FizzBuzz"
elif is_divisible(number, 3):
return "Fizz"
elif is_divisible(number, 5):
return "Buzz"

return str(number)

To make things a little bit more readable, I defined an is_divisible function, which checks if two numbers are divisible, and used that function to translate our main constraints. If none of the rules applies, I return a string cast of the input number as the result.

With that part sorted out, I can use a list comprehension as follows, to produce my final result:

def fizz_buzz(self, number):
if not isinstance(number, int):
raise TypeError
elif number <= 0:
raise ValueError

return [self.process_number(n) for n in range(1, number + 1)]

First, I check for valid input and then used the range() function inside a list comprehension to produce the final result, using our process_number. Here is the solution in action:

## Rust Solution

Now is the time to try our skills with Rust. Let's see how the test suite would look like:

#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_fizzbuzz() {
assert_eq!(fizz_buzz(15), vec!["1", "2", "Fizz", "4", "Buzz", "Fizz", "7", "8",
"Fizz", "Buzz", "11", "Fizz", "13", "14", "FizzBuzz"]);
}
}


As you can see, here I don't test for invalid arguments like in Python or Clojure. Here I rely on Rust's type system, which would prevent passing invalid data types to the fizzbuzz function. Not is time to port my is_divisible function to Rust. Here is the code:

fn is_divisible(number: i32, by: i32) -> bool {
number % by == 0
}


Rust distinguishes between recoverable and unrecoverable errors and provides different facilities to express each one of them. In this case, division by zero is a potential bug, and I could for example panic! if the value of by is equal to zero. Something like:

if by == 0 {
panic!("the value of by can't be equal to zero!");
}


However, I decided to not do that, since Rust itself would raise the same error, when you try to do that sort of crazy stuff. After all Rust supposed to keep us sane :wink::

Now I go forward and implement our main logic, using a match expression like this:

fn to_fizz_buzz<'a>(number: i32) -> String {
match number {
n if is_divisible(n, 3) && is_divisible(n, 5) => "FizzBuzz".to_string(),
n if is_divisible(n, 3) => "Fizz".to_string(),
n if is_divisible(n, 5) => "Buzz".to_string(),
n => n.to_string()
}
}


The logic here is quite straight forward, I check the value of number for different constraints, and return proper instance of String as the result. Now I can use this function, to prepare my final result:

pub fn fizz_buzz(number: i32) -> Vec<String> {
let range: Vec<i32> = (1..number + 1).collect();
range.into_iter().map(to_fizz_buzz).collect()
}


In the first line of this function, I create a vector of i32 value types, containing the values I like to calculate FizzBuzz for. Then I .map those values into to_fizz_buzz function, and collect the final result. It's so close to the functional approach we took in Clojure and Python. Here you can find the final solution and play with it:

\$ open repl.it/@shahinism/FizzBuzz-Rust

## Conclusion

Finding solution for this challenge wasn't challenging at all. However, this provided me with the opportunity to experiment with each language's syntax a bit more and learn new stuff around them.