from typing import List, Set, Tuple, Union

from ImportData import import_data

day: int = 13

sample_data: List[str] = [
    '939',
    '7,13,x,x,59,x,31,19'
]

data_structure: type = Tuple[int, List[Union[int, str]]]


def parse_data(data: List[str]) -> data_structure:  # It sounds like they're setting up something for 'x', so
    ready_time: int = int(data[0])  # we're not going to do all the data re-structuring here
    busses: List[Union[int, str]] = []
    for bus in data[1].split(','):
        busses.append(int(bus) if bus.isnumeric() else bus)
    return ready_time, busses


def part1(data: data_structure) -> int:
    ready_time: int = data[0]
    busses: Set[Union[int, str]] = set(data[1])
    if 'x' in busses:
        busses.remove('x')
    first_bus: int = -1
    delay: int = max(busses) + 1
    for bus in busses:
        this_delay: int = bus - (ready_time % bus)
        if this_delay < delay:
            delay = this_delay
            first_bus = bus
    return first_bus * delay


def fits_constraint(time: int, busses: List[Union[int, str]]) -> bool:
    valid: bool = True
    for i in range(len(busses)):
        if busses[i] != 'x':
            valid &= (time + i) % busses[i] == 0
    return valid


def part2(data: data_structure) -> int:
    busses: List[Union[int, str]] = data[1]
    multiplier: int = 1
    time: int = busses[0] * multiplier
    while not fits_constraint(time, busses):
        multiplier += 1
        time: int = busses[0] * multiplier
    return time


if __name__ == '__main__':
    production_ready = True
    raw_data = import_data(day) if production_ready else sample_data
    print(part1(parse_data(raw_data)))
    print(part2(parse_data(raw_data)))