はじめに
この記事は新人プログラマ向けに問題と回答例を紹介するものです。
これを読んで少しでもプログラムに造詣が深まれば幸いです。
ベテランの方からの別解もお待ちしています。
今回は個人的好みでruby
で書いています。
言語は特に問いません。
FizzBuzz問題とは
wikipediaから引用して説明すると
3で割り切れる場合は「Fizz」、5で割り切れる場合は「Buzz」、両者で割り切れる場合(すなわち15で割り切れる場合)は「Fizz Buzz」
を表示するようなプログラムを組むことです
例えば以下のような感じですね(今回はこっちは焦点じゃないのでツッコミはなしの方向で)
def fizzbuzz(num = 0)
num.times do |i|
i+=1
if i % 15 == 0
puts "fizzbuzz"
elsif i % 5 == 0
puts "buzz"
elsif i % 3 == 0
puts "fizz"
else
puts i
end
end
end
num = ARGV[0].to_i
fizzbuzz(num)
$ ruby fizzbuzz.rb 20
1
2
fizz
4
buzz
fizz
7
8
fizz
buzz
11
fizz
13
14
fizzbuzz
16
17
fizz
19
buzz
プログラマ界隈では常識的な問題として誰もが1度は解いたことのある問題のはずです(多分)
僕も新人教育などで度々例題として挙げますが、いい加減古臭いし新鮮な問題を出したい…
ファンファンのファン問題とは
そこで「ファンファンのファン問題」です
これは皆さんご存知の某アイドルユニットの曲からヒントを得て考えてみました
「ファンファンファン ファンファンのファン」の形をできるだけスマートに表示せよ
規則性としては
- はじめに「ファン」を3回表示
- 次に半角スペースを表示
- 更に「ファン」を2回表示
- 「の」を1回表示
- 「ファン」を1回表示
- 改行する
という順序です
例1
何のひねりもなく書いたらこんな感じ
(1..10).each do |i|
puts 'ファンファンファン ファンファンのファン'
end
ファンファンファン ファンファンのファン
ファンファンファン ファンファンのファン
ファンファンファン ファンファンのファン
ファンファンファン ファンファンのファン
ファンファンファン ファンファンのファン
ファンファンファン ファンファンのファン
ファンファンファン ファンファンのファン
ファンファンファン ファンファンのファン
ファンファンファン ファンファンのファン
ファンファンファン ファンファンのファン
ベタ書きで全くスマートじゃない
「ファン」という同じワードを何回も書いているのでDRYじゃない
例2
(1..5).each do |i|
print 'ファン'
if i%3 == 0
print ' '
end
if i%5 == 0
puts 'のファン'
end
end
ファンファンファン ファンファンのファン
「のファン」の部分がスマートじゃない
またこれは1回目しかうまくいかずこれ以降ループまわしていくとズレてしまう
ファンファンファン ファンファンのファン
ファン ファンファンファン ファンのファン
ファンファン ファンファンファン のファン
ファンファンファン ファンファンのファン
例3
(1..10).each do |i|
(1..6).each do |j|
print 'ファン'
if j%3 == 0
print ' '
end
if j%5 == 0
print 'の'
end
end
puts
end
ファンファンファン ファンファンのファン
ファンファンファン ファンファンのファン
ファンファンファン ファンファンのファン
ファンファンファン ファンファンのファン
ファンファンファン ファンファンのファン
ファンファンファン ファンファンのファン
ファンファンファン ファンファンのファン
ファンファンファン ファンファンのファン
ファンファンファン ファンファンのファン
ファンファンファン ファンファンのファン
無事に規則に沿った形を表示できています
が、2重ループで表現している部分がスマートではないですね
例4
# 「の」が入るタイミングを事前に配列に確保
threshold_array = Array.new
(1..20).each do |n|
# 「の」が挟まるタイミングは等差数列の式により
# an = a + (n-1)d
# an = 5 + (n-1)6
# an = 6n-1
threshold_array.push((6 * n) - 1)
end
(1..60).each do |i|
print 'ファン'
# 3の倍数の時に半角スペース or 改行が挟まる
if i%3 == 0
if i%2 == 0
puts
else
print ' '
end
end
if threshold_array.include?(i)
print 'の'
end
end
ファンファンファン ファンファンのファン
ファンファンファン ファンファンのファン
ファンファンファン ファンファンのファン
ファンファンファン ファンファンのファン
ファンファンファン ファンファンのファン
ファンファンファン ファンファンのファン
ファンファンファン ファンファンのファン
ファンファンファン ファンファンのファン
ファンファンファン ファンファンのファン
ファンファンファン ファンファンのファン
事前に判定配列を作っておくことで2重ループがなくなりました
おわりに
自分で問題を考えておいて、全然スマートな解答が思いつかず四苦八苦しました
結構色んな解法がありそうだなーと思うので是非みなさんポジティブなパッションで挑戦してみてください!