Sean McLemon | Advent of Code

Home | Czech | Blog | GitHub | Advent Of Code | Notes


2016-12-15 - Timing is Everything

(original .ipynb)
puzzle_input_str = open("puzzle_input/day15.txt").read()

test_input_str = """Disc #1 has 5 positions; at time=0, it is at position 4.
Disc #2 has 2 positions; at time=0, it is at position 1."""


def parse_line(line):
    _, rest = line.split("#")
    disc = rest[0]
    positions, rest = rest[1:].removeprefix(" has ").split(" positions; at time=")
    time, rest = rest.split(", it is at position ")
    position = rest.removesuffix(".")
    return (int(disc), int(positions), int(position))


def parse(input_str):
    discs = []
    for line in input_str.split("\n"):
        disc, positions, position = parse_line(line)
        discs.append((disc, positions, position))
    return discs


def find_alignment(discs):
    max_position = [positions for disc, positions, position in discs]
    positions = [position for disc, positions, position in discs]
        
    tick = 0
    while True:
        all_aligned = True
        for disc, position in enumerate(positions):
            all_aligned = all_aligned and ((position + disc) % max_position[disc]) == 0
            positions[disc] = (positions[disc] + 1) % max_position[disc]
        if all_aligned:
            break
            
        tick += 1
    
    return tick - 1


def part_one(input_str):
    discs = sorted(parse(input_str), key=lambda d:d[0])
    return find_alignment(discs)


assert 5 == part_one(test_input_str)
print("part one:", part_one(puzzle_input_str))
part one: 203660
def part_two(input_str):
    discs = sorted(parse(input_str), key=lambda d:d[0])
    discs.append(
        (len(discs), 11, 0)
    )
    return find_alignment(discs)

print("part two:", part_two(puzzle_input_str))
part two: 2408135