# Polyglot Dojo #2: FizzBuzz [2*]

## December 19, 2019

## Updates

**[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:

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'

Can we assume the inputs are valid? No

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:

$ open repl.it/@shahinism/FizzBuzz-Python █

Now let's take a look at the repository's proposed solution. Here it is:

```
class Solution(object):
def fizz_buzz(self, num):
if num is None:
raise TypeError('num cannot be None')
if num < 1:
raise ValueError('num cannot be less than one')
results = []
for i in range(1, num + 1):
if i % 3 == 0 and i % 5 == 0:
results.append('FizzBuzz')
elif i % 3 == 0:
results.append('Fizz')
elif i % 5 == 0:
results.append('Buzz')
else:
results.append(str(i))
return results
```

The main logic used here is the same as mine, but there is a subtle difference which I like to talk about. From our constraints list, we know we can't assume that the input values are valid. So we need to implement the validation logic. In my solution, I ensure the input value is a non-zero integer, which given the task in hand (we expect to perform mathematical operations on the input, and we know the number list should grow by one) integers are quite a reasonable choice.

Yet in repository's solution, they are not ensuring it to be a number type, and
rely on `num is not None`

. Here the function just expect it to be a value (and
it can be anything other than `None`

and negative numbers), so a malicious call
like `fizz_buzz('five')`

would easily pass our main constraints but fail due to
wrong operation error. I usually prefer to limit input types to the minimum
required, which is helpful in situations like this.

## Clojure Solution

As usuall, we first need to translate our test suite to Clojure. The main test would be as simple as this:

```
(ns fizz-buzz-clj.core-test
(:require [clojure.test :refer :all]
[fizz-buzz-clj.core :refer :all]))
(deftest fizz-buzz-test
(testing "calculate the FizzBuzz of 15"
(is (= (fizzbuzz 15) ["1" "2" "Fizz" "4" "Buzz" "Fizz" "7" "8",
"Fizz" "Buzz" "11" "Fizz" "13" "14" "FizzBuzz"]))))
```

Yet, we haven't tested for invalid inputs as our constraints ask for. To cover
this part of our main function, I plan to use Clojure's contract based
programming facility by `{:pre ...}`

syntax. You can find more information about
it from here. But basically, `:pre`

gets a set of condition describing the
constraints of function's parameters, and on each application of the function,
ensures, the provided arguments satisfy its condition. Otherwise, it'll throw an
`AssertionError`

. So for this part of my unit tests, I can use this:

```
(testing "throws error on invalid inputs"
(is (thrown? AssertionError (fizzbuzz 0)))
(is (thrown? AssertionError (fizzbuzz nil))))
```

Quite straightforward, right? The main logic for my Clojure approach, is not much different from the Python solution, however, it contains, some satisfying syntax sugar :sweat_smile:. First I add a function to help me with divisibility check:

```
(defn is-divisible?
[number by]
{:pre [(not= by 0)]}
(= (mod number by) 0))
```

Here you can see the first contract I used which ensures the `is-divisible?`

function would get executed only if the value of `by`

is not equal to zero. Now
I can use this function, to translate a number, to FizzBuzz:

```
(defn to-fizz-buzz
[number]
(cond
(and (is-divisible? number 5) (is-divisible? number 3)) "FizzBuzz"
(is-divisible? number 3) "Fizz"
(is-divisible? number 5) "Buzz"
:else (str number)))
```

Here I used a `(cond ...)`

expression to express the same logic as we had in
Python sample. Now with our main logic implemented, we can write a function to
satisfy our main test case:

```
(defn fizz-buzz
[number]
{:pre [(number? number) (> number 0)]}
(map to-fizz-buzz (range 1 (+ number 1))))
```

Again, you see the `:pre`

conditions to ensure the input values. The I use a
`map`

to apply my `to-fizz-buzz`

function to a range of numbers based on the
input `number`

. Now you can see the final result in action:

$ open repl.it/@shahinism/FizzBuzz-Clojure █

## 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.