FizzBuzzへの道

もうすでに2回ぐらい過去にやってるけど、ブログでFizzBuzzを書くといいらしいと聞いた。

class Fizzer

  def initialize(fz)
    @l = []
    fz.sort{|a, b|
      b[1] <=> a[1]
    }.each do |key, val|
      @l << lambda {|x| (x % val) == 0 ? key.to_s : x}
    end
  end

  def replace(n)
    @l.each do |l|
      n = l.call(n)
    end
    n
  end
end

f = Fizzer.new(Fizz:3, Buzz:5, FizzBuzz:15)

1.upto(100) do |i|
  puts f.replace(i)
end

全然やりかったことと違っていて、ひどいコード。まだぼくにはFizzerクラスすら書けないのかと、うなだれつつ、もう1つ、オープンクラス万歳な感じでやってみた。

class Fixnum

  alias :orig_to_s :to_s

  def to_s
    f = ""
    if (self % 3) == 0 then f += "Fizz" end
    if (self % 5) == 0 then f += "Buzz" end
    return f unless f.empty?
    self.orig_to_s
  end

end

1.upto(100) {|i| p i}

ここここにあるように、FizzBuzzを習得するにはcall/ccとthread、ラムダ計算を使いこなせないとダメらしいので、とても先が長い。しかも、リンク先のthreadを使った例は、mutexすら使わずに(猫が食ったんだとか)、純粋にタイミングだけでエレガントに解いている。最近はやり(?)のTDDもFizzBuzzと深く関係してるらしい。