@m_seki の

I like ruby tooから引っ越し

5年ぶりの組合せとファーストチケット

ファーストチケットっていうのが出ちゃったドラゴンセレクション。初手の7枚にチケットを引いてくる確率を考えてみる。この手のネタは五年ぶり。→ http://d.hatena.ne.jp/m_seki/20070919#1190134698

訂正版

komaさんの記事を見て間違いに気付きました。56枚タネで検算してたらすぐわかったのになー。

  • 全ての組合せと、成功(あるいは失敗)の組合せを調べると確率がわかる
  • 手札に1枚はタネがないと成立しない
  • 7枚のうちタネがn枚、チケットがm枚になる組合せを合計すると成功の組合せ数がわかる。
$fact = Hash.new {|h, k|
  k <= 1 ? 1 : h[k] = k * h[k - 1]
}
$nCm = Hash.new {|h, k|
  n, m = k
  h[k] = $fact[n].div($fact[m] * $fact[n - m])
}

def ticket_p(n_basic, n_ticket = 4)
  sum = 0
  n_other = 60 - (n_basic + n_ticket)
  (1..6).each do |basic|
    (1..4).each do |ticket|
      other = 7 - (basic + ticket)
      next unless (0..n_other) === other
      sum += ($nCm[[n_basic, basic]] *
              $nCm[[n_ticket, ticket]] *
              $nCm[[n_other, other]])
    end
  end
  sum.quo($nCm[[60, 7]])
end

(1..56).each do |basic|
  p [basic, ticket_p(basic).to_f]
end

実行結果。タネの数とタネとチケットのくる確率。今度はあってるかなー。54-56の結果が同じなのが当たり前だけどびっくりした。

% ruby ncm.rb
[1, 0.041604119884749866]
[2, 0.07953247445695691]
[3, 0.11404964986127125]
[4, 0.14540568045751226]
[5, 0.17383659257063544]
[6, 0.19956493788355734]
[7, 0.22280031647283793]
[8, 0.243739889487221]
...
[50, 0.3994993150303987]
[51, 0.3994995325303855]
[52, 0.3994996050303811]
[53, 0.39949962315538]
[54, 0.3994996257446656]
[55, 0.3994996257446656]
[56, 0.3994996257446656]

以下間違い。

  • 全ての組合せと、成功(あるいは失敗)の組合せを調べると確率がわかる
  • nCmっていうメソッドをずいぶん前に書いていた
  • 手札に1枚はタネがないと成立しないので、7枚のうち1枚はすでに決まっている
  • 6枚ひいたうちに1枚でもチケットがあれば成功
  • でもこれは計算が面倒なので、6枚引いたらすべてチケットではなかった組合せを考えてみる。

60枚デッキ。1枚はタネなので、のこりは59。そのうちチケットでないカードは55枚。失敗する組合せは55枚から6枚選んだときの組合せとなる。

  • 全体 = 59C6
  • 失敗 = 55C6
  • 成功 = 59C6 - 55C6
  • 成功する確率 = 成功 / 全体

で計算すると35.66%だと思う。多分。

ポケモンカードゲームBW 拡張パック リューノブレード BOX ポケモンカードゲームBW はじめてセット 全国図鑑版

検算用スクリプト。実際に乱数を使って実験するやつね。

ary = [:ticket] * 4 + [:basic] * 10
ary[59] = nil

basic = 0
ticket = 0
n = 100000
n.times do
  it = ary.sort_by {rand}.to_a[0,7].compact.uniq
  case it
  when [:basic]
    # no ticket
    basic += 1
  when [:ticket]
    # no basic
  when []
    # no basic, no ticket
  else
    basic += 1
    ticket += 1
  end
end
puts "%.4f" % (ticket.quo(n)) # 初手にタネとチケットがくる確率
puts "%.4f" % (ticket.quo(basic)) # 初手にタネがきたときのチケットがくる確率