Skip to content

Instantly share code, notes, and snippets.

@agfor
Last active August 29, 2015 14:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save agfor/8c59d6a6e9a643223f2d to your computer and use it in GitHub Desktop.
Save agfor/8c59d6a6e9a643223f2d to your computer and use it in GitHub Desktop.
Calculate the frequencies of different total face values for rolling n six sided dice.
#Naive version. Takes a couple of minutes for 11 dice on my laptop
#from itertools import product
#from collections import Counter
#
#dice = int(input('How many dice? '))
#result = Counter(map(sum, product(range(1, 7), repeat=dice)))
#print(result)
def choose(n, k):
"""
A fast way to calculate binomial coefficients by Andrew Dalke (contrib).
http://stackoverflow.com/a/3025547/500584
"""
if 0 <= k <= n:
ntok = 1
ktok = 1
for t in range(1, min(k, n - k) + 1):
ntok *= n
ktok *= t
n -= 1
return ntok // ktok
else:
return 0
def freq(sides, dice, amount):
# http://digitalscholarship.unlv.edu/cgi/viewcontent.cgi?article=2852&context=thesesdissertations
m = sides
n = dice
k = amount - dice
total = 0
for j in range(max(m, k)):
term = (-1) ** j
term *= choose(n, j)
term *= choose(n - 1 + k - m * j, n - 1)
total += term
return total
sides = 6
dice = int(input('How many dice? '))
sums = range(dice, dice * sides + 1)
#freqs = [freq(sides, dice, amount) for amount in sums]
freqs = [freq(sides, dice, amount) for amount in sums[:(len(sums) + 1) // 2]]
if len(sums) % 2 == 1:
freqs += freqs[-2::-1]
else:
freqs += freqs[-1::-1]
result = dict(zip(sums, freqs))
print(result)
@brianray
Copy link

brianray commented Aug 3, 2015

nice work

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment