Last active
June 26, 2016 08:48
-
-
Save hiterm/0f700fe0fb4ae562d4fa7e3595ed2876 to your computer and use it in GitHub Desktop.
http://togetter.com/li/866620 の解答(Python3)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# -*- 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) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
【方針】 | |
例えばリールが4つのとき、 | |
1123 | |
という目について、並び順を入れ替えた | |
1231 | |
のような目や、 | |
数字を入れ変えた | |
2234 | |
のような目は同じパターンだと考えることにします。 | |
そして、パターンは全て地道に求めますが、1つのパターンに属する目の総数は組み合わせ的計算で求めることで、高速化しています。 | |
さらにパターンについては自然数の分割との対応があるため、これを用いて求めます。 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment