A little late on the fizz buzz problem
August 27, 2010 § 9 Comments
[tweetmeme service=’bit.ly’]
My two cents in Ruby. Extending the Fixnum class allows you to call .to_fizz_buzz_string
instead of .to_s
if you want the fizz buzz version of an integer rather than the usual string version.
#!/usr/bin/ruby class Fixnum def Fixnum.fizz_buzz_entities { 3 => 'Fizz', 5 => 'Buzz', } end def to_fizz_buzz_string fb = Fixnum::fizz_buzz_entities.inject('') { |result, kv| result << kv[1] if (self % kv[0]).zero?; result } fb.empty? ? self.to_s : fb end end (1..100).each { |i| puts i.to_fizz_buzz_string }
Inspired by The Fizz Buzz problem and diving in too soon and The Fizz Buzz Problem.
Twitter Trackbacks…
It seems that it prints BuzzFizz for 15, while it should be FizzBuzz? (ruby 1.8.7)
Yes, this is a problem with using a hash to contain the entities. As the hash order is indeterminate, then it is possible to get BuzzFizz as well as FizzBuzz depending on how .each enumerates the hash contents. If the order was important, then a different data structure would need to be used, probably an array.
To print out the representations in a deterministic order, use an array instead of a hash. Also, a space between Fizz and Buzz might be more readable:
I’m a big fan of this solution:
from the fizzbuzz gem at http://fizzbuzz.rubyforge.org/svn/trunk/lib/fizzbuzz.rb
Haha! Ok, yes that is pretty clever, took me a little while to understand what was going on there – at first look I thought it was going to be completely random :)
I think one of the original requirements was easy understanding and extensibility – not sure how well this solution would score on them!!
How about getting rid of that return variable you are using:
I couldn’t think of how to test on the result of the inject and return it if appropriate; I’m sure there should be a way. But sticking the number in and removing it again later if necessary works… ;-)
Yes, I had the same problem – I couldn’t think of a neat way either. The gsub is a pretty succinct solution though :)
Just thinking about that, it is something I want to do quite often – return the object itself if it meets some criterion, or something else if it doesn’t. My not-very-flexible solution to that is
I’m sure that could be made rather nicer, allowing elsedo to be a block, for instance (and, indeed, the comparison to be a block…)