Friday, May 06, 2011

ババ抜きのスタートの枚数

トランプのババ抜きは、参加者にカードを配り、同じ数字のカードを捨てることからはじまります。
カードが切れていないと、同じカードが揃っていて有利なスタートとなります。カードがちゃんとシャッフルされているとするなら、何枚からスタートとなるのが妥当なのでしょう?

確率の計算をしてもいいのですが、場合分けが面倒くさかったのでシミュレーションでやってみました。そう、計算をしても答え合わせのためにどのみちシミュレーションはやるんです。

左側が配られた枚数。そのときの右はスタートの枚数です。100回づつ実験しました。
(配った枚数は人数により、ありえない数があるのでところどころ飛んでます。3人でやるなら17枚か18枚、4人なら13枚、5人なら10枚か11枚etc....)

2 1.86
3 2.62
4 3.22
5 3.56
6 4.24
7 4.38
8 4.78
9 5.34
10 5.46
11 5.32
13 5.84
17 6.12
18 6.22
26 5.62

これを見ると、大体5、6枚で安定してるようですね。
プログラムもつけとこ。


from random import randint

numcards = 52
kinds = 13

def f(n):
a = [0 for i in xrange(0, kinds)]

while n > 0:
c = randint(0, kinds-1)
if a[c] < 4:
a[c] += 1
n -= 1

r = 0
for x in a: r += x % 2
return r

def gen_num():
a = set([])
for p in xrange(2, 25):
if numcards % p != 0:
a.add(numcards/p + 1)
a.add(numcards/p)
b = list(a)
b.sort()
return b

def main():
N = 100
for n in gen_num():
r = 0.0
for i in xrange(N):
r += f(n)
print n, r/N

main()

Sunday, May 01, 2011

pythonのdictionaryのsetdefault, pop,getなど

自分用のメモ。

dictionaryでその要素がなければ何とかで、ある場合は何とかという処理をif文で書くことがあるけれど、if "a" in dのようなことを書かずに済む方法。

>>> d = {}
>>> d.setdefault("a", 1)
1
>>> d
{'a': 1}

まだ要素がない場合、1が登録される。
既にある場合は指定とちがって既にある値が返ってくるので分かるという寸法。

>>> d.setdefault("a", 2)
1
>>> d
{'a': 1}
>>>

popにも似た機能がある。

>>> d.pop("c", 1)
1

何もないときの振る舞いがこれ。

返り値を指定しない場合は怒られてしまう。

>>> d.pop("c")
Traceback (most recent call last):
File "", line 1, in
KeyError: 'c'


getにも似たことが言える。

>>> d.get("c")
>>> d.get("c", 1)
1