Skip to content

Instantly share code, notes, and snippets.

@koteitan
Forked from kyodaisuu/bagpuzzle.py
Last active September 11, 2018 17:46
Show Gist options
  • Select an option

  • Save koteitan/bd3563cc4e1ccf91a0ff77fa56cab36d to your computer and use it in GitHub Desktop.

Select an option

Save koteitan/bd3563cc4e1ccf91a0ff77fa56cab36d to your computer and use it in GitHub Desktop.
呪いのかばんパズル
#!/usr/bin/env python3
# 呪いのカバンパズル
# https://togetter.com/li/1265539
from statistics import mean, median, stdev
bag = 1000000 # 残っているカバンの数
rest = 5 # 当たっても大丈夫な回数
# 結果
# 平均: 40.791858 回
# 中央値: 41 回
# 標準偏差: 9.39 回
# 最長: 70 回
# 最短: 5 回
def put_fish(bag, rest):
# カバンを置く数を判定するアルゴリズム
# https://twitter.com/kyodaisuu/status/1039229105357520897
if rest == 1:
return 1
else:
if bag < 2**rest * 2.5: # *2.5 は、平均回数が少なくなるように調整した
return int(bag/2) # 残りのカバンが少ない時は2等分戦略に切り替える
else:
# return int(1000000**((rest-1)/5)) # 等分割方式、平均 41.757 中央値 42
return int(bag**(1-1/rest)+0.5)+rest # bag^(1/rest) 分割 + 微調整
def put_hoshikawa(bag, rest):
table=[1,1,16,256,4096,65536]
return table[rest]
def dist(bag, rest, put):
if bag == 0:
return []
if bag == 1:
return [0]
p = put(bag, rest)
if p >= bag:
p = bag-1
d = []
for i in dist(p, rest-1, put):
d.append (i+1)
for i in dist(bag-p,rest, put):
d.append (i+1)
return d
print('calc fish');
xlist = dist(bag, rest, put_fish)
print('calc hoshikawa');
ylist = dist(bag, rest, put_hoshikawa)
pqlen=max(max(ylist)+1, max(xlist)+1)
p=[0]*pqlen
c=0
for x in xlist:
p[x]=p[x]+1
c=c+1
for x in range(len(p)):
p[x]=p[x]/c
q=[0]*pqlen
c=0
for y in ylist:
q[y]=q[y]+1
c=c+1
for y in range(len(q)):
q[y]=q[y]/c
xwon = 0
ywon = 0
for y in range(len(q)):
for x in range(0,y):
xwon += p[x]*q[y]
for x in range(y,len(p)):
ywon += p[x]*q[y]
print('--------------------');
print('平均 : {0} 回'.format(mean (xlist)))
print('中央値 : {0} 回'.format(median(xlist)))
print('標準偏差: {0} 回'.format(stdev (xlist)))
print('最長 : {0} 回'.format(max (xlist)))
print('最短 : {0} 回'.format(min (xlist)))
print('fish won={0}'.format(xwon))
print('--------------------');
print('平均 : {0} 回'.format(mean (ylist)))
print('中央値 : {0} 回'.format(median(ylist)))
print('標準偏差: {0} 回'.format(stdev (ylist)))
print('最長 : {0} 回'.format(max (ylist)))
print('最短 : {0} 回'.format(min (ylist)))
print('hoshikawa won={0}'.format(ywon))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment