Today we are going to take a quick break from looking at some different library methods for today’s Ruby Tuesday post.
Last Friday I was going back and forth with a teammate over our chat tool about some different programming problems we could use to do some very basic screening of candidates, and I mentioned that if nothing else there is always fizzbuzz.
fizzbuzz, for anybody who at this point has yet to encounter it, even by just blog posts such as this, take a number N
, and prints out fizz
if the number is a multiple of three, buzz
if the number is a multiple of 5, fizzbuzz
if the number is both a multiple of three and five, or else just the number itself if none of the conditions hold true.
While fizzbuzz, isn’t a great problem, and, depending on the circles you are in, can be pretty worthless because most candidates have seen it already, it can still have its place. But, sadly, there are developer candidates we encounter that have a hard time translating the problem above, which states the algorithm in English, directly into code. The reason I think fizzbuzz can be interesting, as I mentioned to my coworker, is it can give candidates a chance to show off some more advanced topics that they wish to show off, if they wish.
After mentioning that benefit to him on Friday, I came across the post “Bro, Do You Even FizzBuzz?!?” on fizzbuzz in Clojure and shows off a solution of not using the modulus operator to determine the result.
I decided I would attempt to translate the solution to Ruby, to prove out the point of our conversation.
def do_fizzbuzz(n) fizz = ['', '', 'fizz'].cycle.lazy buzz = ['', '', '', '', 'buzz'].cycle.lazy fizzbuzz = fizz.zip(buzz).map(&:join) puts (1..n). zip(fizzbuzz). map {|number, translation| if translation.empty? then number else translation end}. join("n") end
First, we declare the “fizzes” as a lazy repeating array of blank strings, where every third is the string ‘fizz’, by using cycle
and lazy
. We do the same for the occurrences of buzz
, but have it be every fifth item in an array.
We then zip
the fizz
and buzz
lazy enumerations together, and then map
over that result joining the two strings together, e.g. ["", ""].join
, ["fizz", ""].join
, ["", "buzz"].join
, or ["fizz", "buzz"].join
.
After we have our lazy enumeration of fizzbuzz translations, we take the range of numbers from 1 to N
, zip
that together with the translations, pick the translation if it is not an empty string, otherwise pick the number, and then join all of the results together with a newline separator, so each entry will print on its own line.
There you have it, a functional programming style fizzbuzz solution that does not use the modulus operator to arrive at a solution.
–Proctor
Pingback: Erlang Thursday Bonus – Functional fizzbuzzProctor It | Proctor It