probability of T total eyes when throwing N dice with S sides

Viewed 1730

I want to calculate the probability of the event that the sum of all eyes of n dice with s sides (numbered from 1 to s) is equal to t. My language is Python 3.

My current approach is pretty much a try-and-count solution and only works for small numbers (running probability(10, 10, 50) already ate all my RAM and forced me to hard reset):

import itertools
def probability(n, s, t):
    all_rolls=list(itertools.product(range(1,s+1), repeat=n))
    target_rolls=[l for l in all_rolls if sum(l)==t]
    return round(len(target_rolls)/len(all_rolls), 4)

But I honestly don't know how else to solve this. Can you please help me to get on the right track?

3 Answers

itertools.product is too slow for big number of sides > 5 and number of sides > 6. On my machine having dice_number: 10 and sides: 10 took one and a half hours to calculate. Instead I used numpy.polypow function to calculate targets and it took less than a second to calculate.

from numpy.polynomial.polynomial import polypow

def probability(dice_number, sides, target):
    """
    Using numpy polynomial
    The number of ways to obtain x as a sum of n s-sided dice
    is given by the coefficients of the polynomial:

    f(x) = (x + x^2 + ... + x^s)^n
    """

    # power series (note that the power series starts from x^1, therefore
    # the first coefficient is zero)
    powers = [0] + [1] * sides
    # f(x) polynomial, computed used polypow in numpy
    poly = polypow(powers, dice_number)
    return poly[target] / sides ** dice_number if target < len(poly) else 0
Related