Sean McLemon | Advent of Code

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


2020-12-12 - Rain Risk

(original .ipynb)

Day 12 puzzle input is a sequence of instructions consisting of an action (N, S, E, W, L, R, F) and an integer quantity (mine is here) whose meanings should be self evident. Part 1 involves assuming you're starting at (0,0) and facing East and moving according to the rules, and finding manhattan distance to the starting position. Part 2 involves interpreting the actions slightly different (N, S, E, W move a "waypoint" around. R and L rotate the waypoint around the user, and F moves forward in multiples of the distance between you and the waypoint) then finding the manhattan distance to the starting position.

test_input_str = """F10
N3
F7
R90
F11"""

puzzle_input_str = open("puzzle_input/day12.txt", "r").read()

def parse_instruction(direction_line):
    action = direction_line[0]
    quantity = direction_line[1:]

    return (action, int(quantity))

def turn_left(d_row, d_col, quantity):
    turns = quantity // 90
    
    while turns > 0:
        d_row, d_col = -d_col, d_row
        turns -= 1
    
    return d_row, d_col
    
def turn_right(d_row, d_col, quantity):
    turns = quantity // 90
    
    while turns > 0:
        d_row, d_col = d_col, -d_row
        turns -= 1
    
    return d_row, d_col

def step_part1(current_row, current_col, d_row, d_col, action, quantity):
    if action == "N":
        current_row -= quantity
    elif action == "S":
        current_row += quantity
    elif action == "E":
        current_col += quantity
    elif action == "W":
        current_col -= quantity
    elif action == "L":
        d_row, d_col = turn_left(d_row, d_col, quantity)
    elif action == "R":
        d_row, d_col = turn_right(d_row, d_col, quantity)
    elif action == "F":
        current_row += quantity * d_row
        current_col += quantity * d_col
        
    return (current_row, current_col, d_row, d_col, quantity)        

def solve(directions_str, stepper, d_row, d_col):
    instruction_lines = directions_str.split("\n")
 
    current_row = 0
    current_col = 0

    for instruction_line in instruction_lines:
        action, quantity = parse_instruction(instruction_line)
        current_row, current_col, d_row, d_col, quantity = stepper(current_row, current_col, d_row, d_col, action, quantity)

    return abs(current_row) + abs(current_col)

assert 25 == solve(test_input_str, step_part1, 0, 1)

solve(puzzle_input_str, step_part1, 0, 1)
1441
def step_part2(current_row, current_col, d_row, d_col, action, quantity):
    if action == "N":
        d_row -= quantity
    elif action == "S":
        d_row += quantity
    elif action == "E":
        d_col += quantity
    elif action == "W":
        d_col -= quantity
    elif action == "L":
        d_row, d_col = turn_left(d_row, d_col, quantity)
    elif action == "R":
        d_row, d_col = turn_right(d_row, d_col, quantity)
    elif action == "F":
        current_row += quantity * d_row
        current_col += quantity * d_col
        
    return (current_row, current_col, d_row, d_col, quantity)        

assert 286 == solve(test_input_str, step_part2, -1, 10)

solve(puzzle_input_str, step_part2, -1, 10)
61616