松江Ruby会議06
http://matsue.rubyist.net/matrk06/
一問目 ランダムソート
問題
1から10までの配列があります。
ランダムに並べ替えてください。
※ただし、Array#shuffle, Array#shuffle!, Array#sample は使用しないでください。
def f
a = (1..10).to_a
# -- ここにコードを記述してください。 --
end
# 三回出力してそれぞれランダムに並び替えられていることを確認します。
f
f
f
解答
def f
a = (1..10).to_a
# -- ここにコードを記述してください。 --
seed = Random.new(rand(10))
loop do
r = seed.rand
r *= 10
r = r.to_s
$r = r.split(//)
$r.delete(".")
i = $r.rindex("0")
$r[i] = "10" if i
$r.uniq!
if $r.size == 10
break
end
end
$r.each_with_index do |v,i2|
$r[i2] = v.to_i
end
p $r
end
# 三回出力してそれぞれランダムに並び替えられていることを確認します。
f
f
f
出力
[6, 1, 7, 4, 3, 8, 2, 9, 10, 5]
[7, 2, 3, 4, 6, 5, 1, 8, 10, 9]
[1, 10, 6, 9, 4, 5, 8, 3, 2, 7]
解説
"# -- ここにコードを記述してください。 --" より説明します。
1行目:seed = Random.new(rand(10))
Randomは乱数を出力するので、それぞれを配列にすればランダムになるわけです。これはその種を制作している段階です。毎回同じ出力にしないため種もランダムにしています。
2行目:loop do
これについては後ほど。
3行目:r = seed.rand
種から乱数を作成します。
4行目:r *= 10
これは、頭の0を取るためです。
5行目:r = r.to_s
splitがNumericでは使えないのでStringにします。
6行目:$r = r.split(//)
1文字ずつ分けます。$がついてるのはスコープを広げるためです。
7行目:$r.delete(".")
小数点を消します。
8行目:i = $r.rindex("0")
0を10にするために、0の位置をあぶりだします。
9行目:$r[i] = "10" if i
0を10にします。ただ0が無いことがあるので(後述)if修飾子をつけています。
10行目:$r.uniq!
同じ数字が入っていてはいけないので、一つずつにします。
11行目:if $r.size == 10
ランダム故、同じ数字が並び10行目で消されて10個にならないことがあります。そのため10になるまで繰り返させています。
12行目:break
10になったら、脱出します。
13行目:end
if文の終わりです。
14行目:end
loopの終わりです。
15行目:$r.each_with_index do |v,i2|
このままだと要素が文字列なので数に戻します。mapでも良かったかな?
16行目:$r[i2] = v.to_i
数値に変えています。
17行目:end
each_with_indexの終わりです。
18行目:p $r
出力です。
感想
作り始めはどうすればいいか思いつかなかったので、 「どんなやり方だろうと勝ちは勝ち」 的発想で、10回(最小)randをやる控えめ(?)なプログラムを書きました。
その後、そういう技もありなんだと知ったので、この乱数を使うプログラムにしました。
二問目 確率の問題
問題
0回から13回までのいずれかの回数だけトランプのカードを引けます。
引いたカードが、すべてスペードのカードである場合の確率を返すプログラムを作成してください。
以下は、トランプの内容です。
トランプの枚数は、52枚です。
トランプの絵柄は、「スペード、クローバー、ハート、ダイヤ」の4つです。
絵柄ごとにカードは、13枚あります。
カードの種類は、「A 2 3 4 5 6 7 8 9 10 J Q K」の13種類です。
解答
#coding: utf-8
deck = ("s1 s2 s3 s4 s5 s6 s7 s8 s9 s10 s11 s12 s13 h1 h2 h3 h4 h5 h6 h7 h8 h9 h10 h11 h12 h13 d1 d2 d3 d4 d5 d6 d7 d8 d9 d10 d11 d12 d13 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13").split
puts "+--+-------------+------------------------------------------------------+"
puts "| 0|0 | |"
percentage2 = 1
13.times do |n|
puts "+--+-------------+------------------------------------------------------+"
card = 52.0 - n
spade = 13 - n
percentage1 = Rational(spade / card)
percentage2 *= percentage1
percentage3 = (percentage2 * 100).to_f
m = n + 1
i = 0
blank = 0
print "|",sprintf("%2d",m)
print "|",sprintf("%.10f",percentage3)
print " " if n != 0
print "|"
str1 = ""
loop {
str1.concat("+")
unless (str1.size) + 3 * m > 54 then
str1.concat("---" * m)
else
break
end
}
str2 = ""
str1.concat("+")
loop {break if str1.size >= 54;str1.concat(" ");blank += 1;}
deck.combination(m) {|c|
spade_card = true
print "|#{str1}|¥n| | |" if str2 == 0
str2.concat("|")
c.each_with_index { |t,idx|
str2.concat t
str2.concat "," if idx + 1 != c.size
spade_card = false if /s/ !‾ t
}
if spade_card
str2.concat("*")
else
str2.concat(" ")
end
if (str2.size) + 3 * m > 52
print sprintf("%52s", str2), "|¥n| | "
str2 = ""
end
}
print "|#{str1}|¥n"
end
puts "+--+-------------+------------------------------------------------------+"
出力
+--+-------------+------------------------------------------------------+
| 0|0 | |
+--+-------------+------------------------------------------------------+
| 1|25.0000000000| |s1*|s2*|s3*|s4*|s5*|s6*|s7*|s8*|s9*|s10*|s11*|s12*|
| | |s13*|h1 |h2 |h3 |h4 |h5 |h6 |h7 |h8 |h9 |h10 |h11 |
| | |h12 |h13 |d1 |d2 |d3 |d4 |d5 |d6 |d7 |d8 |d9 |d10 |
| | |d11 |d12 |d13 |c1 |c2 |c3 |c4 |c5 |c6 |c7 |c8 |c9 |
| | |+---+---+---+---+---+---+---+---+---+---+---+---+---++|
+--+-------------+------------------------------------------------------+
| 2|5.8823529412 | |s1,s2*|s1,s3*|s1,s4*|s1,s5*|s1,s6*|s1,s7*|s1,s8*|
| | |s1,s9*|s1,s10*|s1,s11*|s1,s12*|s1,s13*|s1,h1 |s1,h2 |
| | |s1,h3 |s1,h4 |s1,h5 |s1,h6 |s1,h7 |s1,h8 |s1,h9 |
| | |s1,h10 |s1,h11 |s1,h12 |s1,h13 |s1,d1 |s1,d2 |s1,d3 |
| | |s1,d4 |s1,d5 |s1,d6 |s1,d7 |s1,d8 |s1,d9 |s1,d10 |
| | |s1,d11 |s1,d12 |s1,d13 |s1,c1 |s1,c2 |s1,c3 |s1,c4 |
| | |s1,c5 |s1,c6 |s1,c7 |s1,c8 |s1,c9 |s1,c10 |s1,c11 |
| | |s1,c12 |s1,c13 |s2,s3*|s2,s4*|s2,s5*|s2,s6*|s2,s7*|
| | |s2,s8*|s2,s9*|s2,s10*|s2,s11*|s2,s12*|s2,s13*|s2,h1 |
| | |s2,h2 |s2,h3 |s2,h4 |s2,h5 |s2,h6 |s2,h7 |s2,h8 |
| | |s2,h9 |s2,h10 |s2,h11 |s2,h12 |s2,h13 |s2,d1 |s2,d2 |
| | |s2,d3 |s2,d4 |s2,d5 |s2,d6 |s2,d7 |s2,d8 |s2,d9 |
| | |s2,d10 |s2,d11 |s2,d12 |s2,d13 |s2,c1 |s2,c2 |s2,c3 |
| | |s2,c4 |s2,c5 |s2,c6 |s2,c7 |s2,c8 |s2,c9 |s2,c10 |
| | |s2,c11 |s2,c12 |s2,c13 |s3,s4*|s3,s5*|s3,s6*|s3,s7*|
| | |s3,s8*|s3,s9*|s3,s10*|s3,s11*|s3,s12*|s3,s13*|s3,h1 |
| | |s3,h2 |s3,h3 |s3,h4 |s3,h5 |s3,h6 |s3,h7 |s3,h8 |
| | |s3,h9 |s3,h10 |s3,h11 |s3,h12 |s3,h13 |s3,d1 |s3,d2 |
| | |s3,d3 |s3,d4 |s3,d5 |s3,d6 |s3,d7 |s3,d8 |s3,d9 |
| | |s3,d10 |s3,d11 |s3,d12 |s3,d13 |s3,c1 |s3,c2 |s3,c3 |
| | |s3,c4 |s3,c5 |s3,c6 |s3,c7 |s3,c8 |s3,c9 |s3,c10 |
| | |s3,c11 |s3,c12 |s3,c13 |s4,s5*|s4,s6*|s4,s7*|s4,s8*|
| | |s4,s9*|s4,s10*|s4,s11*|s4,s12*|s4,s13*|s4,h1 |s4,h2 |
| | |s4,h3 |s4,h4 |s4,h5 |s4,h6 |s4,h7 |s4,h8 |s4,h9 |
| | |s4,h10 |s4,h11 |s4,h12 |s4,h13 |s4,d1 |s4,d2 |s4,d3 |
| | |s4,d4 |s4,d5 |s4,d6 |s4,d7 |s4,d8 |s4,d9 |s4,d10 |
| | |s4,d11 |s4,d12 |s4,d13 |s4,c1 |s4,c2 |s4,c3 |s4,c4 |
| | |s4,c5 |s4,c6 |s4,c7 |s4,c8 |s4,c9 |s4,c10 |s4,c11 |
| | |s4,c12 |s4,c13 |s5,s6*|s5,s7*|s5,s8*|s5,s9*|s5,s10*|
| | |s5,s11*|s5,s12*|s5,s13*|s5,h1 |s5,h2 |s5,h3 |s5,h4 |
| | |s5,h5 |s5,h6 |s5,h7 |s5,h8 |s5,h9 |s5,h10 |s5,h11 |
| | |s5,h12 |s5,h13 |s5,d1 |s5,d2 |s5,d3 |s5,d4 |s5,d5 |
| | |s5,d6 |s5,d7 |s5,d8 |s5,d9 |s5,d10 |s5,d11 |s5,d12 |
| | |s5,d13 |s5,c1 |s5,c2 |s5,c3 |s5,c4 |s5,c5 |s5,c6 |
| | |s5,c7 |s5,c8 |s5,c9 |s5,c10 |s5,c11 |s5,c12 |s5,c13 |
| | |s6,s7*|s6,s8*|s6,s9*|s6,s10*|s6,s11*|s6,s12*|s6,s13*|
| | |s6,h1 |s6,h2 |s6,h3 |s6,h4 |s6,h5 |s6,h6 |s6,h7 |
| | |s6,h8 |s6,h9 |s6,h10 |s6,h11 |s6,h12 |s6,h13 |s6,d1 |
| | |s6,d2 |s6,d3 |s6,d4 |s6,d5 |s6,d6 |s6,d7 |s6,d8 |
| | |s6,d9 |s6,d10 |s6,d11 |s6,d12 |s6,d13 |s6,c1 |s6,c2 |
| | |s6,c3 |s6,c4 |s6,c5 |s6,c6 |s6,c7 |s6,c8 |s6,c9 |
| | |s6,c10 |s6,c11 |s6,c12 |s6,c13 |s7,s8*|s7,s9*|s7,s10*|
| | |s7,s11*|s7,s12*|s7,s13*|s7,h1 |s7,h2 |s7,h3 |s7,h4 |
| | |s7,h5 |s7,h6 |s7,h7 |s7,h8 |s7,h9 |s7,h10 |s7,h11 |
| | |s7,h12 |s7,h13 |s7,d1 |s7,d2 |s7,d3 |s7,d4 |s7,d5 |
| | |s7,d6 |s7,d7 |s7,d8 |s7,d9 |s7,d10 |s7,d11 |s7,d12 |
| | |s7,d13 |s7,c1 |s7,c2 |s7,c3 |s7,c4 |s7,c5 |s7,c6 |
| | |s7,c7 |s7,c8 |s7,c9 |s7,c10 |s7,c11 |s7,c12 |s7,c13 |
| | |s8,s9*|s8,s10*|s8,s11*|s8,s12*|s8,s13*|s8,h1 |s8,h2 |
| | |s8,h3 |s8,h4 |s8,h5 |s8,h6 |s8,h7 |s8,h8 |s8,h9 |
| | |s8,h10 |s8,h11 |s8,h12 |s8,h13 |s8,d1 |s8,d2 |s8,d3 |
| | |s8,d4 |s8,d5 |s8,d6 |s8,d7 |s8,d8 |s8,d9 |s8,d10 |
| | |s8,d11 |s8,d12 |s8,d13 |s8,c1 |s8,c2 |s8,c3 |s8,c4 |
| | |s8,c5 |s8,c6 |s8,c7 |s8,c8 |s8,c9 |s8,c10 |s8,c11 |
| | |s8,c12 |s8,c13 |s9,s10*|s9,s11*|s9,s12*|s9,s13*|
| | |s9,h1 |s9,h2 |s9,h3 |s9,h4 |s9,h5 |s9,h6 |s9,h7 |
| | |s9,h8 |s9,h9 |s9,h10 |s9,h11 |s9,h12 |s9,h13 |s9,d1 |
| | |s9,d2 |s9,d3 |s9,d4 |s9,d5 |s9,d6 |s9,d7 |s9,d8 |
| | |s9,d9 |s9,d10 |s9,d11 |s9,d12 |s9,d13 |s9,c1 |s9,c2 |
| | |s9,c3 |s9,c4 |s9,c5 |s9,c6 |s9,c7 |s9,c8 |s9,c9 |
| | |s9,c10 |s9,c11 |s9,c12 |s9,c13 |s10,s11*|s10,s12*|
| | |s10,s13*|s10,h1 |s10,h2 |s10,h3 |s10,h4 |s10,h5 |
| | |s10,h6 |s10,h7 |s10,h8 |s10,h9 |s10,h10 |s10,h11 |
| | |s10,h12 |s10,h13 |s10,d1 |s10,d2 |s10,d3 |s10,d4 |
| | |s10,d5 |s10,d6 |s10,d7 |s10,d8 |s10,d9 |s10,d10 |
| | |s10,d11 |s10,d12 |s10,d13 |s10,c1 |s10,c2 |s10,c3 |
| | |s10,c4 |s10,c5 |s10,c6 |s10,c7 |s10,c8 |s10,c9 |
| | |s10,c10 |s10,c11 |s10,c12 |s10,c13 |s11,s12*|s11,s13*|
| | |s11,h1 |s11,h2 |s11,h3 |s11,h4 |s11,h5 |s11,h6 |
・
・
・
・
・
解説
こちらは少しまとめて。
みれば分かるようにこれは表です。
5行目、10行目などはその一部です。
11〜14行目は確率の計算となっています。なので、説明は省いておきます。
15行目はパーセントに換算しています。
本来は、これで終わりです。ただ、ライヴコーディング 大喜利 と言うからにはやはり面白い解答がいいと思い、考えた中で "実際どれぐらいなのか" と具体的に分かってもらうため、表にしました。
38行目でcombinantionとありますが、これはすべての組み合わせを試すものです。そしてそのあと出力しています。
※実際に僕のMacで実行したら12時間以上実行しても終わりが見えませんでした。