すでにご存知の方も多いと思いますが、改めてこんな問題

プレーヤーの前に閉じた3つのドアがあって、1つのドアの後ろには景品の新車が、2つのドアの後ろには、はずれを意味するヤギがいる。プレーヤーは新車のドアを当てると新車がもらえる。プレーヤーが1つのドアを選択した後、司会のモンティが残りのドアのうちヤギがいるドアを開けてヤギを見せる。

ここでプレーヤーは、最初に選んだドアを、残っている開けられていないドアに変更してもよいと言われる。
ここでプレーヤーはドアを変更すべきだろうか?
モンティ・ホール問題 - Wikipedia

ふと、これをプログラムにしたらどうなるんだろうと思ってやってみました。

モンティ・ホールのスクリプト

そしてできたのがこれ。
司会とかプレイヤーとかの概念を削ぎ落とすと身も蓋も面白みもない関数となりました🐐

import random def monty_hall(do_change): # 3つの選択肢から一つ選ぶ choice = random.choice([True, False, False]) # 司会がはずれのうちの一つを開け、2択になった想定 # 変更なし(do_change == False)ならもとの値を返す # 変更する(do_change == True)ならもとの値の否定を返す return not choice if do_change else choice

確かめる

とりあえず変更する場合としない場合とで1000回試行してみます。

def play(do_change, n=1000): sum = 0 # 描画のため、n回目までの累計正解回数を格納 return [sum := sum + (1 if monty_hall(do_change) else 0) for i in range(n)] import pandas as pd result = pd.DataFrame({ # 絶対変更するマン "a": play(True), # 絶対変更しないマン "b": play(False) }) import matplotlib.pyplot as plt result.plot(grid=True) plt.show()

見事に変更すれば $\frac{2}{3}$ 、変更しなければ $\frac{1}{3}$ という結果になりました。

まとめ

で、まとめというかmonty_hall関数をみれば分かる通り、変更しなければ正解する割合は $\frac{1}{3}$ に収束するのは明らかです。
そして変更した場合は結果が逆になるだけなので、正解割合が $\frac{2}{3}$ となるのも当然なわけです。

コード書くまで「変更したら $\frac{1}{2}$ じゃねぇの?」とか思ってた自分が恥ずかしい…🐐🚛
以上!