0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

あそび大全

Last updated at Posted at 2024-10-11

問題

  • サイコロ5つをふる、そのうち6が出なかった目を全て振り直す。さらにもう一度6が出なかった目を全て振り直す。この時、全ての目が6になる確率を求めたい

実装

import math

y = 1/6
n = 5/6

def all_pattern():
    all_patterns = []
    for i in range(0,6):
        for j in range(0, i+1):
            all_patterns.append((i, j))
    return all_patterns

def calc_prob(num, i):
    """
    num: サイコロの個数
    i: 6が出る回数
    """
    return y**i * n**(num-i) * math.comb(num, i)

for i in range(1,6):
    for j in range(0, i+1):
        print(f"サイコロの個数: {i}, 6が出る回数: {j} = {calc_prob(i, j)}")

def calc_prob_reroll(pattern):
    # 1回目に指定した個数の6が出る確率
    num_six_1 = 5 - pattern[0]
    prob_1 = calc_prob(5, num_six_1)
    if pattern[0] == 0:
        return prob_1

    num_six_2 = pattern[0] - pattern[1]
    prob_2 = calc_prob(pattern[0], num_six_2)
    if pattern[1] == 0:
        return prob_1 * prob_2

    num_six_3 = pattern[1]
    prob_3 = calc_prob(pattern[1], num_six_3)
    return prob_1 * prob_2 * prob_3

for pattern in all_pattern():
    print(f"{pattern}: {calc_prob_reroll(pattern)}")

print("確率の合計: ", sum(calc_prob_reroll(pattern) for pattern in all_pattern()))

実行結果

(0, 0): 0.00012860082304526745
(1, 0): 0.0005358367626886143
(1, 1): 0.0004465306355738454
(2, 0): 0.0008930612711476908
(2, 1): 0.0014884354519128181
(2, 2): 0.0006201814382970076
(3, 0): 0.0007442177259564091
(3, 1): 0.001860544314891023
(3, 2): 0.0015504535957425194
(3, 3): 0.000430681554372922
(4, 0): 0.0003100907191485037
(4, 1): 0.0010336357304950123
(4, 2): 0.0012920446631187658
(4, 3): 0.0007178025906215365
(4, 4): 0.00014954220637948678
(5, 0): 5.1681786524750625e-05
(5, 1): 0.00021534077718646097
(5, 2): 0.00035890129531076836
(5, 3): 0.00029908441275897367
(5, 4): 0.000124618505316239
(5, 5): 2.0769750886039836e-05
確率の合計:  0.013272056011374656

シミュレーションによる検算

  • 疑似乱数を使って実際にたくさんサイコロを振れば、上記の計算が合っているかの検算ができる

  • なんとこれはchatgptがやってくれた!

    • 書いてくれたコード
    import numpy as np
    
    # サイコロを5つ振り、2回振り直すシミュレーション
    def roll_dice():
        # 初回のサイコロを振る
        dice = np.random.randint(1, 7, 5)
        
        # 6が出ていない目を振り直し(1回目)
        dice[dice != 6] = np.random.randint(1, 7, np.sum(dice != 6))
        
        # 再度、6が出ていない目を振り直し(2回目)
        dice[dice != 6] = np.random.randint(1, 7, np.sum(dice != 6))
        
        # 全て6になっているかどうかを確認
        return np.all(dice == 6)
    
    # シミュレーションを実行する回数
    n_trials = 1000000
    success_count = sum(roll_dice() for _ in range(n_trials))
    
    # 全てのサイコロが6になる確率を求める
    probability = success_count / n_trials
    probability
    
    • 実際答えが正しいことが確かめられた

数学的な計算をgptにさせられないか?

  • 数学的に計算するんじゃなくて、シミュレーションで計算して確率を求める方向に(指示してないのに)もって言ってたのおもろい

  • その後、数学的な計算も実装されるよう指示したところ、2回目の試行で一部のサイコロが6になる可能性を考慮できていなかった。

  • しかし、そのことを指摘すると、正しいコードを実装して、数学的な計算で確率を求めることに成功していた!

  • 会話のリンク

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?