What about two dice?

Ruimin Pan
4 min readJul 5, 2023

--

Everyone knows how to calculate the chance of getting a 6 from throwing a standard die with numbers from 1 to 6 on its 6 faces. “But what about two dice?” That was the question my 10 year old asked me yesterday…

The probability of getting any value from 1 throw of a standard die can be (easily) expressed in the table below:

For two dice, the number of possible values is still small enough for us to list them all in a short table:

Now here’s a fun question to think about: what is the probability of getting something more than 9 by throwing two dice? The answer can be quickly figured out using the table above: probability of getting a sum greater than 9 = (number of cases where the sum of the two dice is 10, 11, or 12) / (total number of possible combinations) = (3+2+1) / (1+2+…+4+3+2+1) = 6 / 36 = 1/6.

Ok, so far so good. At least that’s good enough for my 10 year old. After my kid went to bed, I started thinking about how this can be extended to N dice each with M faces (those who play Dungeons and Dragons will know what I mean…). What then?

Formally expressed, if we are given N dice each with M faces (with values from 1 to M), what’s the probability of getting a sum greater than a certain integer X?

Well, building on what we did for 2 dice, we can say this probability can be expressed with

where P(sum=i) is the probability of the sum being a particular value i (1+X ≤ i ≤ M*N). To calculate P(sum=i), we can find out the number of possible combinations to make up i with N dice, then divide this number by the total number of possible combinations, just like what we did for the case with two dice.

While it might seem straightforward to find out the number of possible combinations when there are 2 dice, when the number N becomes large, it can be too expensive to do so. Luckily, we can always think recursively: suppose we throw the N dice 1 by 1 and we have tossed N-1 dice so far, then to find out how many combinations we have in total, we can simply do:

where f(N, M, X) is the number of possible combinations given N dice and the sum being X. Since we have already thrown N-1 dice, we can consider all possible results out of the first N-1 throws. e.g., if X = 10 (sum of all throws is 10), N = 3 (3 dice), if in the first N-1 = 2 throws, we reached the sum of X-j =7, then the only choice for the last (Nth) throw would be to throw j = X-7 = 10–7 = 3. Since the last throw can only have a value j from 1 to M (1 < j < M), to get X in the N throws, the first N-1 throws can only have a sum of X-j, j = 1…M.

Using X = 10, M = 6, N = 2 (2 dice) as an example, the sum would be:

Note f(1, 6, 9), f(1, 6, 8) and f(1, 6, 7) should all be 0 because we can’t possibly get 7, 8 or 9 in 1 throw. The number of possible outcomes for f(1, 6, 6), f(1, 6, 5) and f(1, 6, 4) are all 1, so f(2, 6, 10) = 1+1+1 = 3.

In fact,

This essentially gives us the base case for the recursion. Let’s write some Python code for this:

def dice_sum(n, m, x):
if n == 1:
if x >= 1 and x <= m:
return 1
else:
return 0

sum = 0
for k in range(1, m+1):
sum += dice_sum(n-1, m, x-k)
return sum

This will give us the number of combinations given the number of dice n, number of faces m on each dice and the sum x we are aiming for. Once we have f(N, M, X), we can calculate the probability of getting a sum greater than the value X as:

def dice_prob_greater(n, m, x):
"""
probability of n dice (each m faces) adding up to greater than x
"""
total = n*m;
denom = 0
numerator = 0
for i in range(x+1, total+1):
numerator += dice_sum(n,m,i)

denom = numerator
for i in range(1, x+1):
denom += dice_sum(n,m,i)

return numerator / denom

Of course, we can make the code more efficient by using proper dynamic programming (recursion + memoization, see my article Simple dynamic programming with dice). And an iterative (non-recursive) version should also be possible.

--

--

Ruimin Pan
0 Followers

Optimization (theory and practice), Imaging and Computer Vision, Deep signal processing, Software engineering