何も意識せずに書いたコード
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からカウントアップするから、不適。
ううむ。惜しいなあ。