Sean McLemon | Advent of Code

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


2015-12-14 - Reindeer Olympics

(original .ipynb)

Puzzle input is a description of speed, flight + rest cycles of various reindeer. In part one we find out which reindeer travelled the furthest after 2503 time steps. In part two we find which has the greatest "score" (i.e. was in the lead for the most number of time steps) after the same length of time.

puzzle_input_str = open("./puzzle_input/day14.txt").read()


def reinder_stepper(speed, flight_seconds, rest_seconds):
    while True:
        for _ in range(flight_seconds):
            yield speed
            
        for _ in range(rest_seconds):
            yield 0
        

def parse_line(line):
    tokens = line.split(" ")
    return tokens[0], reinder_stepper(int(tokens[3]), int(tokens[6]), int(tokens[-2]))


def parse_input(input_str):
    for line in input_str.split("\n"):
        yield parse_line(line)
        

def part_one(input_str, time_limit=2503):
    all_reindeer = list(parse_input(input_str))
    distances = {r[0]:0 for r in all_reindeer}
    elapsed = 0
    
    while elapsed < time_limit:
        for reindeer, stepper in all_reindeer:
            distances[reindeer] += next(stepper)
        
        elapsed += 1

    return max(distances.values())


test_input_str = """Comet can fly 14 km/s for 10 seconds, but then must rest for 127 seconds.
Dancer can fly 16 km/s for 11 seconds, but then must rest for 162 seconds."""


assert   16 == part_one(test_input_str, 1)
assert  160 == part_one(test_input_str, 10)
assert 1120 == part_one(test_input_str, 1000)


print("part one:", part_one(puzzle_input_str))
part one: 2640
def part_two(input_str, time_limit=2503):
    all_reindeer = list(parse_input(input_str))
    distances = {r[0]:0 for r in all_reindeer}
    score = {r[0]:0 for r in all_reindeer}
    elapsed = 0
    
    while elapsed < time_limit:
        for reindeer, stepper in all_reindeer:
            distances[reindeer] += next(stepper)
        
        leader_score = max(distances.values())
        leaders = [reindeer for reindeer in distances if distances[reindeer] == leader_score]
        for leader in leaders:
            score[leader] += 1
            
        elapsed += 1

    return max(score.values())


assert 689 == part_two(test_input_str, 1000)

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