Formula 1 Without Formulas

This problem was inspired by a Formula 1 race, which at one point had 5 pairs of same-team drivers next to each other in position order. Curious how likely that kind of thing was to happen, but not wanting to think about it too hard while watching a race, instead I decided to code up a super-quick simulation.

In Formula 1, teams can field two drivers, and there are twenty drivers in the race. We can represent that like this, with equal letters indicating drivers from the same team.

drivers = list('aabbccddeeffgghhiijj')

This is hacky code, so instead of using something nice like a Counter, let’s just build a quick dictionary mapping number of pairs to the times we see that situation occur. Limit the total number of simulations to 100,000 (big enough to get decently accurate results, small enough to run in under a second).

counts = {num_pairs: 0 for num_pairs in range(11)}
lim = 100000

Now, let’s code a super simple simulation of this situation. Randomly reorder drivers on each run. Then, look at all consecutive pairs. If both drivers belong to the same team, count that as a pair. Finally, save all sim results in the big counts dictionary.

for i in range(lim):
    shuffle(drivers)
    count = 0
    for a, b in zip(drivers[:-1], drivers[1:]):
        if a == b:
            count += 1
    counts[count] += 1

Now that we have counts, it’s pretty simple to convert to averages.

averages = {num_pairs: count / lim for num_pairs, count in counts.items()}

Then we just print out the percentage of times we saw each number of pairs out of all the times we ran the simulation.

for num_pairs, fraction in averages.items():
    print(f'{num_pairs} {fraction:.2%}')

Here are some sample results:

0 35.85%
1 37.69%
2 18.96%
3 6.00%
4 1.26%
5 0.21%
6 0.02%
7 0.00%
8 0.00%
9 0.00%

Based on the model of “race orders are random” this is a pretty good result, without too much noise across trials. However, in real races, factors like starting order, car similarity, or team cooperation might play a larger role in determining the actual orderings which are more likely.

This isn’t as accurate as actually doing the math, but it only took a minute to write up, and didn’t require any hard thinking. I thought it was pretty cool to have an answer this quickly, and as a bonus it’d be super easy to extend this to graph the answer to this question, or to ask slightly different follow-up questions.