塵芥回顧録

なるべく更新していきたいが、ネタがない。

3×3ビンゴで8ビンゴを計算する

前回の3×3ビンゴを計算する方法を考える

nurupon.hatenablog.com


プログラムをpythonで書いてみる

kaisu = 26
for i in range(8,kaisu+1):
    lpnum = 7**(i-8) #パターン数を代入(簡易化のため7の乗数で代入)
    ans = 0
    for j in range(lpnum): #i回目で8ビンゴする確率(確率パターン組み合わせlpnum個)
        tmp = j
        bef = 0
        tmpans = 1
        for k in range(i-8): #組み合わせ計算
            #そのままだと2,3回重複の場合と3,2回目重複の場合のように
            #同じパターンを加算してしまうためifでbreak
            #値は10進数を1~7の7進数として変換して扱う
            if bef > tmp%7+1:
                tmpans = 0 #中断しているためtmpans=0としてansに加算しない
                j += 7**k * (bef-tmp%7) #次の計算すべき値までjを進める
                break
            bef = tmp%7+1 #上if文判定のために代入
            tmpans *= bef
            tmp //= 7 #次の桁へ
        ans += tmpans
    ansper = 100 * ans * (7*6*5*4*3*2*1)/8**(i-1)
    print('[',i,'回目]',round(ansper,3),'%',sep='')

直接計算すると上のようなプログラムになるが、回数が増えると組み合わせが指数的に増加し、非常に時間がかかるため現実的じゃない。


そこで、組み合わせの数え方を考えてみる。

上図のように9回目は赤実線枠の値を足した値と1/8を8回目の時の確率にかけた確率となる。

青枠の10回目では9回目の値に1をかけた値と9回目の内2以降の値に2をかけた値、9回目の内3以降の値に3をかけた値、9回目の内4以降の値に……を足した値と(1/8)2を8回目の時の確率にかけた確率となる。

この方法を用いると毎回同じ繰り返し回数のため、比較的短時間で求めることができる。


以下プログラム

kaisu = 50
n = [1,2,3,4,5,6,7]
for i in range(8, kaisu+1):
    if(i!=8):
        for j in range(7):
            for k in range(j+1,7):
                n[j] += n[k]
            n[j] *= j+1
    ans = 100 * n[0] * (7*6*5*4*3*2*1)/8**(i-1)
    print('[',i,'回目]',round(ans,3),'%',sep='')

※8回目の時は1パターンしかないため例外として処理