アウトプットのネタに困ったらこれ!?
こちらの記事を参考にしてビンゴカード作成問題を解いてみました。まずは可読性よりも初心者なりに答えを出すことを心がけたため、とりあえず「動くだけ」のコードとなっております。
シンプルなコードを追求する上での基本的な考え方や、より有効なメソッドに対する理解も深めていきたいので、ご意見いただけるとありがたいです。
問題は下記のような出力結果を得ることです。
B:1~15のどれか
I:16~30のどれか
N:31~45のどれか
G:46~60のどれか
O:61~75のどれか
B | I | N | G | O
13 | 22 | 32 | 48 | 61
3 | 23 | 43 | 53 | 63
4 | 19 | | 60 | 65
12 | 16 | 44 | 50 | 75
2 | 28 | 33 | 56 | 68
初めは以下のようなコードで「動くだけ」のプログラムを作ってみました。割と短時間で解いたのですが、単純なロジックを繋ぎ合わせただけです。
puts " B | I | N | G | O"
def rand_b
b = rand(1..15)
if b <= 9
print " #{b} |"
else
print " #{b} |"
end
end
def rand_i
i = rand(16..30)
print " #{i} |"
end
def rand_n
n = rand(31..45)
print " #{n} |"
end
def rand_g
g= rand(46..60)
print " #{g} |"
end
def rand_o
o = rand(61..75)
print " #{o} "
end
5.times do |count|
rand_b
rand_i
if count == 2
print " |"
else
rand_n
end
rand_g
rand_o
puts "\n"
end
ずいぶん長いコードとなりましたが、理屈としてはこういうことです。
5.times do
print rand(1..15)
print rand(16..30)
print rand(31..45)
print rand(46..60)
print rand(1..75)
puts "\n"
end
このコードに、空欄に関する条件を色々と付け加えただけです。
##### しかしながら、このコードには、重複する値が出てしまうという、重大な欠陥がございました。その問題を解消したスマートな解答に関してはコメント欄を参考にしてください。
ただし、コメントをそのまま真似するのではなく、ちゃんと自分でもう一度考えて、値の重複を避けたコードを書きたかったため、初めに解いた時と同じ思考スタイルを適用しながら、解き直してみました。
puts " B | I | N | G | O"
b = (1..15).to_a.sample(5)
i = (16..30).to_a.sample(5)
n = (31..45).to_a.sample(5)
g = (46..60).to_a.sample(5)
o = (61..75).to_a.sample(5)
5.times do |count|
printf("%3d", b[count])
print " |"
print " #{i[count]} |"
if count == 2
print " |"
else
print " #{n[count]} |"
end
print " #{g[count]} |"
print " #{o[count]} "
puts "\n"
end
それがこのコードです。「rand」ではなく「sample」を用いて重複を避けた形です。あくまでもとりあえず「動くだけ」であり、シンプルでスマートな解答ではありません。
優秀なプログラマーであれば、どのような思考プロセスを経て、どのような答えに辿り着くのかを教えてくださると嬉しいです。