似非プログラマのうんちく

「似非プログラマの覚え書き」出張版

Ruby で FizzBuzz を満喫する

Scala にだいぶSAN値を削られたのでここいらで Ruby に日和ろう(苦笑)。

その 1 : Object#tap を利用する

to_fizzbuzz = -> n {
  "".tap do |_|
    _ << "Fizz" if n % 3 == 0
    _ << "Buzz" if n % 5 == 0
    break n if _.empty?
  end
}

puts 1.upto(100).map(&to_fizzbuzz)

RubyObject#tap はブロック内で自分自身に対して行われた破壊的変更が保証される。break が発動するとそれらの変更を破棄して強制的に別の値を返すことが出来る。発動しなければブロック内で行われた破壊的変更を適用した自身が返ることになる。

さくっと lambda 奴を使っておくと Enumerable#mapProc オブジェクトを渡す Ruby らしい書き方で処理が記述できる。

その 2 : Hash を利用する

Scala 編で Map を使ったやつの元ネタ。

Applicators = {3 => :Fizz, 5 => :Buzz}

to_fizzbuzz = -> n {
  fb = Applicators.select{|_| n % _ == 0}.values.join
  fb.empty? ? n : fb
}

puts 1.upto(100).map(&to_fizzbuzz)

やってることはほぼ一緒。メソッド名が違うだけ。

その 3 : Enumerable#zip を利用する

fizz = [nil] * 2 << :Fizz
buzz = [nil] * 4 << :Buzz

1.upto(100).zip(fizz.cycle, buzz.cycle) do |n, *f|
  puts f.any? ? f.join : n
end

ネットで見つけてきた。nilany の使い方が Ruby っぽくてお気に入りである。

続きを読む