LoginSignup
12
12

More than 5 years have passed since last update.

モンティ・ホール問題をGoでやってみる

Last updated at Posted at 2015-09-02

モンティ・ホール問題 - Wikipedia

直感とずれていることで有名なやつですね。Goの練習もかねて。

montyhall.go
package main

import (
    "fmt"
    "math/rand"
    "time"
)

func shuffle(a map[int]bool) {
    rand.Seed(time.Now().UnixNano())
    for i := range a {
        j := rand.Intn(i + 1)
        a[i], a[j] = a[j], a[i]
    }
}

func main() {

    counter1 := 0
    counter2 := 0
    loop := 100000

    for i := 0; i < loop; i++ {
        // 全3個あたりがひとつのくじを用意
        lottery := map[int]bool{0: true, 1: false, 2: false}
        // シャッフル
        shuffle(lottery)

        // ひとつ選ぶ
        choice := rand.Intn(3)

        // 選びなおさない場合、当たっていたらカウント
        if lottery[choice] == true {
            counter1++
        }

        // 選んでないものからハズレをひとつ取り除く
        for k, v := range lottery {
            if (k != choice) && v == false {
                delete(lottery, k)
                break
            }
        }
        // 残っている方に選びなおす
        for k := range lottery {
            if k != choice {
                choice = k
                break
            }
        }
        // 選びなおした場合、当たっていたらカウント
        if lottery[choice] == true {
            counter2++
        }

    }
    // 普通に選んだ場合
    fmt.Println(counter1)
    // 選びなおした場合
    fmt.Println(counter2)
}

100000回くじをひいて、普通に選んだ場合と選びなおした場合の当たった回数

$ go run montyhall.go
33427
66573
$ go run montyhall.go
33324
66676

コード書いてても直感と合わない感じすごい…これ普通に33%だと思うんだけど
(シャッフルのあたりとか雑なので厳密ではないですが、明らかに有意ですね)

12
12
2

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
12
12