松江Ruby会議06 ライヴコーディング大喜利の解答

  • 6
    いいね
  • 0
    コメント
この記事は最終更新日から1年以上が経過しています。

松江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時間以上実行しても終わりが見えませんでした。