simulate the evolution of a highway with only one road that is a loop the highway is divided in cells each cell can have at most one car in it the highway is a loop so when a car comes to one end it will come out on the other each car is represented by its speed from 0 to 5 some information about speed 1 means that the cell on the highway is empty 0 to 5 are the speed of the cars with 0 being the lowest and 5 the highest highway listint where every position and speed of every car will be stored probability the probability that a driver will slow down initialspeed the speed of the cars a the start frequency how many cells there are between two cars at the start maxspeed the maximum speed a car can go to numberofcells how many cell are there in the highway numberofupdate how many times will the position be updated more information here https en wikipedia orgwikinagele28093schreckenbergmodel examples for doctest simulateconstructhighway6 3 0 2 0 2 0 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 simulateconstructhighway5 2 2 3 0 2 0 1 0 1 0 0 1 0 1 1 0 1 1 1 1 1 1 1 0 1 build the highway following the parameters given constructhighway10 2 6 6 1 6 1 6 1 6 1 6 1 constructhighway10 10 2 2 1 1 1 1 1 1 1 1 1 get the distance between a car at index carindex and the next car getdistance6 1 6 1 6 2 1 getdistance2 1 1 1 3 1 0 1 3 2 0 3 getdistance1 1 1 1 2 1 1 1 3 1 4 here if the car is near the end of the highway update the speed of the cars update1 1 1 1 1 2 1 1 1 1 3 0 0 5 1 1 1 1 1 3 1 1 1 1 4 update1 1 2 1 1 1 1 3 0 0 5 1 1 3 1 1 1 1 1 beforce calculations the highway is empty add 1 to the current speed of the car and cap the speed number of empty cell before the next car we can t have the car causing an accident randomly a driver will slow down the main function it will simulate the evolution of the highway simulate1 2 1 1 1 3 2 0 0 3 1 2 1 1 1 3 1 1 1 2 1 0 1 1 1 0 1 1 simulate1 2 1 3 4 0 0 3 1 2 1 3 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 change the position based on the speed with to create the loop commit the change of position build the highway following the parameters given construct_highway 10 2 6 6 1 6 1 6 1 6 1 6 1 construct_highway 10 10 2 2 1 1 1 1 1 1 1 1 1 create a highway without any car place the cars arbitrary number may need tuning get the distance between a car at index car_index and the next car get_distance 6 1 6 1 6 2 1 get_distance 2 1 1 1 3 1 0 1 3 2 0 3 get_distance 1 1 1 1 2 1 1 1 3 1 4 may need a better name for this if the cell is not empty then we have the distance we wanted here if the car is near the end of the highway update the speed of the cars update 1 1 1 1 1 2 1 1 1 1 3 0 0 5 1 1 1 1 1 3 1 1 1 1 4 update 1 1 2 1 1 1 1 3 0 0 5 1 1 3 1 1 1 1 1 beforce calculations the highway is empty add 1 to the current speed of the car and cap the speed number of empty cell before the next car we can t have the car causing an accident randomly a driver will slow down the main function it will simulate the evolution of the highway simulate 1 2 1 1 1 3 2 0 0 3 1 2 1 1 1 3 1 1 1 2 1 0 1 1 1 0 1 1 simulate 1 2 1 3 4 0 0 3 1 2 1 3 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 change the position based on the speed with to create the loop commit the change of position
from random import randint, random


def construct_highway(
    number_of_cells: int,
    frequency: int,
    initial_speed: int,
    random_frequency: bool = False,
    random_speed: bool = False,
    max_speed: int = 5,
) -> list:
    

    highway = [[-1] * number_of_cells]  
    i = 0
    initial_speed = max(initial_speed, 0)
    while i < number_of_cells:
        highway[0][i] = (
            randint(0, max_speed) if random_speed else initial_speed
        )  
        i += (
            randint(1, max_speed * 2) if random_frequency else frequency
        )  
    return highway


def get_distance(highway_now: list, car_index: int) -> int:
    

    distance = 0
    cells = highway_now[car_index + 1 :]
    for cell in range(len(cells)):  
        if cells[cell] != -1:  
            return distance  
        distance += 1
    
    return distance + get_distance(highway_now, -1)


def update(highway_now: list, probability: float, max_speed: int) -> list:
    

    number_of_cells = len(highway_now)
    
    next_highway = [-1] * number_of_cells

    for car_index in range(number_of_cells):
        if highway_now[car_index] != -1:
            
            next_highway[car_index] = min(highway_now[car_index] + 1, max_speed)
            
            dn = get_distance(highway_now, car_index) - 1
            
            next_highway[car_index] = min(next_highway[car_index], dn)
            if random() < probability:
                
                next_highway[car_index] = max(next_highway[car_index] - 1, 0)
    return next_highway


def simulate(
    highway: list, number_of_update: int, probability: float, max_speed: int
) -> list:
    

    number_of_cells = len(highway[0])

    for i in range(number_of_update):
        next_speeds_calculated = update(highway[i], probability, max_speed)
        real_next_speeds = [-1] * number_of_cells

        for car_index in range(number_of_cells):
            speed = next_speeds_calculated[car_index]
            if speed != -1:
                
                index = (car_index + speed) % number_of_cells
                
                real_next_speeds[index] = speed
        highway.append(real_next_speeds)

    return highway


if __name__ == "__main__":
    import doctest

    doctest.testmod()