或るゲームのくじの確率(その2)

ちょっと前に、Yahoo!知恵袋の問題で
ゲームのくじの確率を計算して欲しいです・当たりは14%です... - Yahoo!知恵袋
というのを、Ruby で強引に解いた記事を書いた(参照)。確率は 8.06% くらいと求まったのだが、これは乱数を使った推定である。

しかし、よく考えてみたら、手計算で出すのがむずかしいだけで、きちんと厳密解を出すのはそれほどむずかしいことではない。で、実際に Ruby を計算機代わりに使って、解いてみた。

解き方はこんな感じである。まず、1セットで当りが 0, 1, 2 回になる確率ををそれぞれ p0, p1 ,p2 とすると、3 回以上になる確率 p3 は p3 = 1 - p0 - p1 - p2 である。m 個の中から n 個を選ぶ組み合わせの数を mCn と書くとすると、
    
    
となる。あとは 3 セットで当りが

  • 7 回の確率

    

  • 8 回の確率

    

  • 9 回の確率

    
と場合分けされるから、求める確率はこれらの和。実際に計算してみると、8.069288762862017% となる。これは推定の値に近い。

Ruby を計算機として使うと、こんな感じ。

Hit = 0.14; Blank = 1 - Hit
p0 = Blank ** 10
p1 = Hit * (Blank ** 9) * 10
p2 = (Hit ** 2) * (Blank ** 8) * 45
p3 = 1 - p0 - p1 - p2

h7 = p3 * p3 * p1 * 3 + p3 * p2 * p2 * 3
h8 = p3 * p3 * p2 * 3
h9 = p3 * p3 * p3

puts h7 + h8 + h9    #=>0.08069288762862017

もちろん電卓で計算することも可能。ただ、答えを分数で求めるのは面倒だ。これも Ruby で出せるかなあ。

そうか、分数で計算するには、Rational クラスを使えばいいわけだ。とすると、一行目の Hit = 0.14Hit = Rational(14, 100) に変更するだけで求められる。Ruby すごい。すると結果は
    
となる。これを小数に直すと、0.08069288762862016 となる。


なお、上で出てきた組み合わせ mCn は、Ruby で次のようにメソッドにできる。

def factorial(n)    #階乗
  (1..n).to_a.inject(:*)
end

def cbn(m, n)
  (n != 0 and m != n) ? ( factorial(m) / (factorial(m - n) * factorial(n)) ) : 1
end

puts cbn(10, 2)   #=>45