Day 19

Here we've got a task that involves tracing a maze of sorts where we can move along lines. We must continue straight for as long as possible until hitting a + sign. When we reach a letter, we'll add it to a collection.

In [1]:
import numpy as np
import string

pipes = open('/Users/Sven/py_files/aoc_2017/d19_input.txt').readlines()
pipes = [pipe.replace('\n', '') for pipe in pipes]
pipes[:5]
Out[1]:
['                                                                                                                                                         |                                               ',
 '                                                 +-------------------------------------------------------------------------------------------------------------------------------------------+           ',
 '                                                 |                                                                                                       |                                   |           ',
 ' +---------+                                     |         +---------------+         +-------------+           +---+   +-----------------------------------------------------------------+   |           ',
 ' |         |                                     |         |               |         |             |           |   |   |                                 |                               |   |           ']

It's kinda hard to see that they're the same lengths

In [2]:
pipe_lens = [len(x) for x in pipes]
max(pipe_lens) == min(pipe_lens)
Out[2]:
True

Maybe we'll start with finding out where the first pipe is:

In [3]:
first_col = pipes[0].find('|')
first_row = 0
loc = np.array([first_row, first_col])

# maybe use the names down, up, left, and right to indicate the direction traveling
start_dir = 'd' 
dirs = set(['u', 'd', 'l', 'r'])
updown = set(['u', 'd'])
leftright = dirs - updown
move_vecs = dict({'d' : np.array([1, 0]), 'u' : np.array([-1, 0]), 'l' : np.array([0, -1]), 'r' : np.array([0, 1])})

# record what we've seen
visited = ''
# and what we could see
letters = string.ascii_letters

# finally turn the pipes into a np.array
pipes = np.array(pipes)

Alright, now we need to think of a way through this.... The directions lead me to believe that the maze is actually a single path and that there are other, disconnected paths that also lie in the input. I think we'll want to write a function that can continue to go straight and one that will figure out which way to turn in the even that we're at a plus.

In [4]:
# Direction moving functions

# get a pipe symbol from an np array
def get_symbol(loc):
    return(pipes[loc[0]][loc[1]])

# Function to advance in a straight line:
def advance(loc, direction):
    move_vec = move_vecs[direction]
    while not get_symbol(loc + move_vec) in ['+', ' ']:
        loc += move_vec
        #print(loc)
        # if we hit a letter append it to the list
        if get_symbol(loc) in letters:
            global visited # back to global nonsense
            visited += get_symbol(loc)
    # now we should return the location
    loc += move_vec
    return(loc)

# Determine which way to turn
def turn(loc, direction):
    
    # have to make 90 degree turns so we know what to look for
    if direction in updown:
        turn_dirs = leftright
    else:
        turn_dirs = updown
    
    for dir in turn_dirs:
        if not get_symbol(loc + move_vecs[dir]) in [' ', '+']:
            return(dir)
    
    # If we didn't hit, return this flag
    return('done')

Okay now we need to put these things together. We'll repeat moving and turning until we hit done.

In [5]:
while start_dir != 'done':
    loc = advance(loc, start_dir)
    start_dir = turn(loc, start_dir)
row 4 column 2
In [6]:
visited
Out[6]:
'SXPZDFJNRL'

Part 2

We're now asked how long the path is that it travels. This seems very easy to add...

In [7]:
# Reset conditions:
steps_walked = 0
first_col = pipes[0].find('|')
first_row = 0
loc = np.array([first_row, first_col])
start_dir = 'd' 

# modify advance function so we add to steps_walked
def advance2(loc, direction):
    global steps_walked
    move_vec = move_vecs[direction]
    while not get_symbol(loc + move_vec) in ['+', ' ']:
        loc += move_vec
        # if we hit a letter append it to the list
        steps_walked += 1
    # now we should return the location
    loc += move_vec
    steps_walked += 1
    return(loc)

while start_dir != 'done':
    loc = advance2(loc, start_dir)
    start_dir = turn(loc, start_dir)
steps_walked
Out[7]:
18126

ez