A Series of Tubes

Part 1 & 2


In [98]:
from collections import defaultdict

def parse_route(input_path):
    route = defaultdict(lambda: ' ')
    with open(input_path, 'rt') as f_input:
        for i, line in enumerate(f_input):
            for j, v in enumerate(list(line.rstrip('\n'))):
                route[(i, j)] = v
                if (i == 0) and (v == '|'): start = (i, j)
    return route, start

In [99]:
import re

def move(curr_pos, curr_dir, route):
    if route[curr_pos] == '+':
        for e in [(1, 0), [0, 1], [-1, 0], [0, -1]]:
            next_dir = (e[0], e[1])
            next_pos = (curr_pos[0] + next_dir[0], curr_pos[1] + next_dir[1])
            if (route[next_pos] != ' ') and (curr_dir[0]*next_dir[0] + curr_dir[1]*next_dir[1] == 0):
                break
    else:
        next_pos = (curr_pos[0] + curr_dir[0], curr_pos[1] + curr_dir[1])
        next_dir = curr_dir
        if route[next_pos] == ' ':
            next_pos = None
    return next_pos, next_dir

def follow_route(input_path):
    word = ''
    route, curr_pos = parse_route(input_path)
    curr_dir = (1, 0)
    steps = 0
    while curr_pos is not None:
        curr_pos, curr_dir = move(curr_pos, curr_dir, route)
        steps += 1
        if (curr_pos is not None) and re.search('[A-Z]', route[curr_pos]):
            word += route[curr_pos]
    return word, steps

Test


In [100]:
follow_route('input.test1.txt')


Out[100]:
('ABCDEF', 38)

Solution


In [101]:
follow_route('input.txt')


Out[101]:
('LOHMDQATP', 16492)