Search code examples
pythoncombinationssimulationpython-itertools

How to calculate all combinations of a Formula 1 race in python/itertools


I wanted to make a championship calculator/simulator to help figure out the different combinations of how a driver could win the championship.

After digging around I figured I needed to use itertools. Below is what I have so far. The problem is that at the moment it is generating every position for every driver when I only need it to assign 1 position per driver for every combination.

def Sim():
    drivers = ["Lewis Hamilton","Valteri Bottas","Max Verstappen","Sergio Perez","Lando Norris","Daniel Riccardo","Carlos Sainz","Charles Lecerc","Pierre Gasly","Yuki Tsunoda","Kimi Raikonnen","Antonio Giovnazzi","Sebastian Vettel","Lance Stroll","Fernando Alonso","Estaban Ocon","George Russel","Nicholas Latifi","Mick Schumacher","Nikita Mazepin"]
    pos = ["20", "19", "18", "17", "16", "15", "14", "13", "12", "11", "10", "9", "8", "7", "6", "5", "4", "3", "2", "1"]
    c = list(itertools.product(drivers, pos))
    print(c)

Solution

  • What you are looking at are permutations (not a product). But 20 cars can finish in 2,432,902,008,176,640,000 permutations of positions. That's 121,645,100,408,832,000 per winning driver.

    Even if you were using the right function (permutations), you would not be able to process them all even on a supercomputer, let alone storing them in a list.

    drivers = ["Lewis Hamilton","Valteri Bottas","Max Verstappen","Sergio Perez","Lando Norris","Daniel Riccardo","Carlos Sainz","Charles Lecerc","Pierre Gasly","Yuki Tsunoda","Kimi Raikonnen","Antonio Giovnazzi","Sebastian Vettel","Lance Stroll","Fernando Alonso","Estaban Ocon","George Russel","Nicholas Latifi","Mick Schumacher","Nikita Mazepin"]
    
    from itertools import permutations
    
    for raceResult in permutations(drivers):
        print(*(f"{p}:{d}" for p,d in enumerate(raceResult[:3],1)),end=" ... ")
        print(*(f"{p}:{d}" for p,d in enumerate(raceResult[18:],18)))
    
    1:Lewis Hamilton 2:Valteri Bottas 3:Max Verstappen ... 18:Mick Schumacher 19:Nikita Mazepin
    1:Lewis Hamilton 2:Valteri Bottas 3:Max Verstappen ... 18:Nikita Mazepin 19:Mick Schumacher
    1:Lewis Hamilton 2:Valteri Bottas 3:Max Verstappen ... 18:Nicholas Latifi 19:Nikita Mazepin
    1:Lewis Hamilton 2:Valteri Bottas 3:Max Verstappen ... 18:Nikita Mazepin 19:Nicholas Latifi
    1:Lewis Hamilton 2:Valteri Bottas 3:Max Verstappen ... 18:Nicholas Latifi 19:Mick Schumacher
    ...
    

    What would be more manageable is to look only at the permutations of the first 3 (which there are only 6,840 for your 19 drivers):

    for raceResult in permutations(drivers,3):
        print(*(f"{p}:{d}" for p,d in enumerate(raceResult,1)))
    
    1:Lewis Hamilton 2:Valteri Bottas 3:Max Verstappen
    1:Lewis Hamilton 2:Valteri Bottas 3:Sergio Perez
    1:Lewis Hamilton 2:Valteri Bottas 3:Lando Norris
    1:Lewis Hamilton 2:Valteri Bottas 3:Daniel Riccardo
    1:Lewis Hamilton 2:Valteri Bottas 3:Carlos Sainz
    1:Lewis Hamilton 2:Valteri Bottas 3:Charles Lecerc
    1:Lewis Hamilton 2:Valteri Bottas 3:Pierre Gasly
    1:Lewis Hamilton 2:Valteri Bottas 3:Yuki Tsunoda
    1:Lewis Hamilton 2:Valteri Bottas 3:Kimi Raikonnen
    1:Lewis Hamilton 2:Valteri Bottas 3:Antonio Giovnazzi
    ...