Fizz-Buzz 問題

Fizz-Buzz 問題というのがちょっとまえネットで流行っていたらしい。

どうしてプログラマに・・・プログラムが書けないのか?

問題はこうだ。

1から100までの数をプリントするプログラムを書け。ただし3の倍数のときは数の代わりに「Fizz」と、5の倍数のときは「Buzz」とプリントし、3と5両方の倍数の場合には「FizzBuzz」とプリントすること。

「ちゃんとしたプログラマであれば、これを実行するプログラムを2分とかからずに紙に書き出せるはずだ」という言葉に挑発されて、自分もやってみた。2分以内でできるか内心ヒヤヒヤしながら。使った言語はやっぱり Ruby

最初の答えはこれ。

(1..100).each do |i|
  if i % 15 == 0
    puts "FizzBuzz"
  elsif i % 5 == 0
    puts "Buzz"
  elsif i % 3 == 0
    puts "Fizz"
  else
    puts i
  end
end

なんとか2分以内にはできた。まあ、合っているとは思う。もっと短くできないか考えてみた。

1.upto(100){|i|s="";(s="Buzz")if i%3==0;(s<<"Fizz")if i%5==0;puts(s=="" ? i:s)}

合計79文字。短いけど、素直な作り。ネットを検索すると、もっと短いコードに出くわした。

(1..100).each{|i|puts ["Fizz#{s=['Buzz'][i%5]}"][i%3]||s||i}

しめて60文字。でもかなり邪悪なコードだな。もっと短いコードはないだろうか?

はてブを見てたら、さらに短いコード発見。

1.upto(?d){|i|i%3<1&&x=:Fizz;puts i%5<1?"#{x}Buzz":x||i}

これは56文字。お見事。