FizzBuzz 問題

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

ちゃんとしたプログラマであれば、これを実行するプログラムを2分とかからずに紙に書き出せるはずだ。

やってみた。

1 から 100 まで

1.upto(100) do |i|
end

プリントする

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

3 の倍数なら Fizz

1.upto(100) do |i|
  if i % 3 == 0
    puts 'Fizz'
  else
    puts i
  end
end

5 の倍数なら Buzz

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

3 と 5 の公倍数なら FizzBuzz

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

一応これで完成。続いて最適化してみる。

ループ内の処理をメソッドとして抽出

def fizz_buzz(i)
  if (i % 3 == 0) && (i % 5 ==0)
    puts 'FizzBuzz'
  elsif i % 3 == 0
    puts 'Fizz'
  elsif i % 5 == 0
    puts 'Buzz'
  else
    puts i
  end
end

1.upto(100) do |i|
  fizz_buzz(i)
end

puts を fizz_buzz の外に出す

def fizz_buzz(i)
  if (i % 3 == 0) && (i % 5 ==0)
    return 'FizzBuzz'
  elsif i % 3 == 0
    return 'Fizz'
  elsif i % 5 == 0
    return 'Buzz'
  else
    return i
  end
end

1.upto(100) do |i|
  puts fizz_buzz(i)
end

約数判定の重複を整理する

def fizz_buzz(i)
  result = ""
  result += 'Fizz' if i % 3 == 0
  result += 'Buzz' if i % 5 == 0
  result = i if result.empty?
  result
end

1.upto(100) do |i|
  puts fizz_buzz(i)
end

おしまい。


ちなみに世間では最短ワンライナー競争とか剰余を使わない縛りとかで盛り上がっている模様。
私は可読性重視なのでその辺はパスしとく。