2023東京大学・文科・第3問(シミュレータ)
Python を用いて上記のシミュレータをできるだけ単純に作成してみた。この問題については ↓
黒玉3個、赤玉4個、白玉5個が入っている袋から玉を1個ずつ取り出し、取り出した玉を順に1列に12個並べる。
ただし、袋から個々の玉が取り出される確率は等しいものとする。
(1) どの赤玉も隣り合わない確率 p を求めよ。
(2) どの赤玉も隣り合わないとき、どの黒玉も隣り合わない条件付確率 q を求めよ。
実装
玉を文字と見立ててシャッフルと 'rr'
が含まれるか、 'bb'
が含まれるかを判定。(1) は 'rr'
が含まれる割合を計算すればよいので平均を取り、(2) は 'rr'
と 'bb'
両方含まれる確率を計算し (1) の答えで割ればよい…はず
import numpy as np
import random
class Sim(object):
"""2023東京大学・文科・第3問 シミュレーター
黒玉3個、赤玉4個、白玉5個が入っている袋から玉を1個ずつ取り出し、取り出した玉を順に1列に12個並べる。
ただし、袋から個々の玉が取り出される確率は等しいものとする。
(1) どの赤玉も隣り合わない確率 p を求めよ。
(2) どの赤玉も隣り合わないとき、どの黒玉も隣り合わない条件付確率 q を求めよ。
"""
def __init__(self, x):
self.x = x
def __call__(self):
# 玉をランダムシャッフル
random.shuffle(self.x)
# 文字列として処理できるよう結合
y = ''.join(self.x)
# 'rr' が y に含まれていない(True or False)
a1 = 'rr' not in y
# a1 & 'bb' が y に含まれていない(True or False)
a2 = a1 & ('bb' not in y)
return [a1, a2]
# 試行回数
N = 10000000
# 玉: 黒玉3個、赤玉4個、白玉5個
x = ['b'] * 3 + ['r'] * 4 + ['w'] * 5
# シミュレータ
sim = Sim(x)
# N 回シミュレート
result = np.array([sim() for i in range(N)])
# 平均確率を算出(numpy は True=1, False=0 として計算できる)
a1, a2 = np.mean(result, axis=0)
# 表示
print("(1)", a1)
print("(2)", a2 / a1)
>>> (1) 0.2543706
>>> (2) 0.613201761524327
まとめ
多分できたはず。まぁ 15 分くらいでちゃちゃっと作った割には比較的わかりやすくシンプルに実装できたのではないでしょうか? ちなみに計算すると…
(1) 25.45%
(2) 61.31%
くらいになるよう。