直感とずれていることで有名なやつですね。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%だと思うんだけど
(シャッフルのあたりとか雑なので厳密ではないですが、明らかに有意ですね)