# Introduction

Recently, my significant other approached me with a probability puzzle: Roll a die repeatedly until the sum over all rolls exceeds twelve. What sum is the most probable to occur? Below, I’ll answer the puzzle by intuition first and then verify my answer via simulation in Python.

Classical probability theory defines the probability of an event as the total number of its favorable outcomes divided by the number of all possible results. The most likely sum to occur should hence be the sum that can arise in most ways. If the sum over all dice rolls has to exceed twelve, then there are only six possible outcomes of this “experiment”: Anything between thirteen and eighteen is possible. Now, how should we count the number of ways each sum of dice can arise?

Since the number of dice rolled is not known beforehand, we cannot take comfort in exact equations. Regardless, we can reason our way through. To that end, notice that there is only one way to end the experiment at 18: You roll three sixes in a row. In contrast, there are at least two ways to complete the dice rolls at 17. First, the dice sum to twelve, and you get a five on your last roll. Alternatively, your dice sum to eleven and the next roll results in a six. Already, a pattern emerges: Sums closer to twelve seem to occur in more ways.

• s18 = {(12, 6)}
• s17 = {(12, 5); (11, 6)}
• s16 = {(12, 4); (11, 5); (10, 6)}
• s15 = {(12, 3); (11, 4); (10, 5); (9, 6)}
• s14 = {(12, 2); (11, 3); (10, 4); (9, 5); (8, 6)}
• s13 = {(12, 1); (11, 2); (10, 3); (9, 4); (8, 5); (7, 6)}

The list above shows the set of all possible outcomes and the ways to achieve them on the last roll. Thirteen should be the most probable outcome. However, we cannot yet put a probability on it. Each prior sum is itself a compound outcome: Twelve, eleven, etc., may arise in numerous ways. Hence, let’s simulate the entire process in Python and verify my intuition.

## Simulation in Python

The listing below shows a simple Python program that simulates the entire process. The function throw_die() returns a random, uniformly distributed integer between 1 and 6. The function run_experiment() does the actual dice rolling and returns the required sum. Finally, main() runs the experiment 10,0000 times and prints the result to screen. When done, the program output supports my intuition.

```from random import randint
from collections import Counter

def throw_die(sides=6):
return randint(1, sides)

def run_experiment(cut=12):
sum_dice = 0
while sum_dice <= cut:
sum_dice += throw_die()
return sum_dice

def main():
NTRIALS = 100000
results = [run_experiment()
for _ in range(NTRIALS)]
print(Counter(results))
```

Three variations of this program are immediately apparent. First, you could alter the number of sides of the die (six by default). Second, you could change the cut-off point (twelve by default). Finally, you could increase the number of trials. The latter increases the precision of the result. The former two options are more interesting. Playing around with them, first, proves the result independent of the size of the die, and, second, shows that the most probable outcome of this experiment is always the cut-off value + 1.

## Conclusion

This post has shown how to combine intuition with simulation in Python to answer a probability puzzle. Let’s see what puzzle makes it into my inbox next.