読者です 読者をやめる 読者になる 読者になる

私が歌川です

@utgwkk が書いている

ぼくのかんがえた最短のFizzBuzz

何も意識せずに書いたコード

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

何の変哲もないコードだ。178バイト。(インデントは半角スペース2つ)
これを、なんとかして短くしていこう。

まず、do や end はいちいち書いていると長すぎる。これは{}で代用できる。
しかし、if~elsif~else の then や end は代用できない。ううむ。

1.upto(100){|i|
  if i % 15 == 0 then
    puts 'FizzBuzz'
  elsif i % 5 == 0 then
    puts 'Buzz'
  elsif i % 3 == 0 then
    puts 'Fizz'
  else
    puts i
  end
}

173バイト。ううむ、なんだかすっきりしないコードだ。
……待てよ、三項演算子を使えばコードは一気に短くなるのでは?

1.upto(100){|i|
  puts i % 15 == 0 ? 'FizzBuzz' : i % 5 == 0 ? 'Buzz' : i % 3 == 0 ? 'Fizz' : i
}

おお! 一気に99バイトまで短くなった。
更に余計な空白などを削っていけば、

1.upto(100){|i|puts i%15==0?'FizzBuzz':i%5==0?'Buzz':i%3==0?'Fizz':i}

69バイト! とうとうワンライナーになった。
まだまだ削れるだろう。……どこを?

……

あっ……!

i%15==0 は、i%15<1 に置き換えてもいいじゃないか……!
これで3バイトずつ削減できる!

できあがったコード

1.upto(100){|i|puts i%15<1?'FizzBuzz':i%5<1?'Buzz':i%3<1?'Fizz':i}

解説

1.upto(100){|i|

1から100まで変数iをカウントアップしながら{}の中を実行するよ。

puts i%15<1?'FizzBuzz':i%5<1?'Buzz':i%3<1?'Fizz':i}

i が15で割り切れるとき、FizzBuzz
i が5で割り切れるとき、Buzz
i が3で割り切れるとき、Fizz
それ以外は、i
を表示するよ。おしまい。

66バイトのFizzBuzz。これだけでもかなり短い。しかしもう少し短くならないだろうか?
101.timesとしてやれば、

1.upto(100)
101.times

と、2バイト短くなる! が、この場合は0からカウントアップするから、不適。
ううむ。惜しいなあ。