Skip to content

Instantly share code, notes, and snippets.

@hiterm
Last active June 26, 2016 08:48
Show Gist options
  • Save hiterm/0f700fe0fb4ae562d4fa7e3595ed2876 to your computer and use it in GitHub Desktop.
Save hiterm/0f700fe0fb4ae562d4fa7e3595ed2876 to your computer and use it in GitHub Desktop.
http://togetter.com/li/866620 の解答(Python3)
# -*- coding: utf-8 -*-
# for Python 3
# リールの数
num_reel = 3
# 自然数を正整数の和に分割 和の順序は考えない
# 返り値はリストのリスト
# 各要素リストlsに対し、ls[i]が数字iの個数を表す
# 例えば 4 = 1 + 1 + 2 なら [0, 2, 1]
# アルゴリズムは http://mogproject.blogspot.jp/2011/12/generating-integer-partitions-with-c.html
def partition(n):
if n == 0:
return [[0]]
if n == 1:
return [[0, 1]]
res = [] # 結果を入れる変数
for ls in partition(n - 1):
templ = list(ls) # リストのコピー templは一時的な変数
templ[1] += 1
res.append(templ)
templ = list(ls)
i = 0
while templ[i] == 0:
i += 1
if templ[i] == 1:
if i == len(templ) - 1:
templ[i] += -1
templ.append(1)
else:
templ[i] += -1
templ[i + 1] += 1
res.append(templ)
return res
# permutationからpermutation_listまでは、
# 重複を数えるための関数
# m個からn個とった並び替えの総数
def permutation(m, n):
res = 1
for i in range(m - n + 1, m + 1):
res *= i
return res
def factorial(n):
res = 1
for i in range(1, n + 1):
res *= i
return res
# リストlsに対し、ls[i]種類のものがi個ずつあるときの並び替えの総数
# 例えば[0, 3, 2, 2]ならa,b,c,d,d,e,e,f,f,f,g,g,gの並び替え
def permutation_list(ls):
sum = 0
for i, x in enumerate(ls):
sum += i * x
res = factorial(sum)
for i, x in enumerate(ls):
if x != 0:
for j in range(x):
res //= factorial(i)
return res
# 賞金がnになる場合の数
def num_cases(n):
all_pat = [ls for ls in partition(num_reel) \
if len(ls) == n + 1 and ls[n] >= 1]
# 数字は10種類なので、条件に合わないものは除く
all_pat = filter(lambda ls: sum(ls) <= 10, all_pat)
res = 0
for ls in all_pat:
s = sum(ls) # sは数字の種類の数
temp = permutation(10, s) * permutation_list(ls)
for x in ls: # 数字の入れ替えと順番の入れ替えの重複を除く
temp //= factorial(x)
res += temp
return res
# 期待値expを求める
exp = 0
for i in range(1, num_reel + 1):
exp += i * num_cases(i)
exp = exp / (10 ** num_reel)
print(exp)
【方針】
例えばリールが4つのとき、
1123
という目について、並び順を入れ替えた
1231
のような目や、
数字を入れ変えた
2234
のような目は同じパターンだと考えることにします。
そして、パターンは全て地道に求めますが、1つのパターンに属する目の総数は組み合わせ的計算で求めることで、高速化しています。
さらにパターンについては自然数の分割との対応があるため、これを用いて求めます。
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment