For Day 12, the problem revolves around navigating a ship using a set of navigational instructions. The instructions look like this:

F10
N3
F7
R90
F11
F2
F2
F2
R180
F10

The instructions move the ship in a cardinal direction N, S, E, W, Rotate the ship, or move Forward, using the current rotation. This problem is solved easily with a simple navigation routine:

def navigate(steps, visualize):
states = []

ship = Position(0, 0)

if visualize:

for action, value in steps:
if action == "N":
ship.y += value
elif action == "S":
ship.y -= value
elif action == "E":
ship.x += value
elif action == "W":
ship.x -= value
elif action == "L":
elif action == "R":
elif action == "F":
ship.x += value
ship.y += value
ship.x -= value
ship.y -= value

if visualize:

return ship, states

The “F” action block would be perfect for a switch statement, if only Python had them.

The answer to the puzzle is the Manhattan distance from the starting point, after all steps have been executed.

A small test execution:

Part 2 was essentially the same, but instead of rotating the ship, the target waypoint is moved, and the F directive move the ship to the waypoint. This can be done with an almost identical routine:

waypoint = Position(10, 1)
ship = Position(0, 0)
for action, value in steps:
if action == "N":
waypoint.y += value
elif action == "S":
waypoint.y -= value
elif action == "E":
waypoint.x += value
elif action == "W":
waypoint.x -= value
elif action == "L":
for _ in range(value // 90):
waypoint.x, waypoint.y = -waypoint.y, waypoint.x
elif action == "R":
for _ in range(value // 90):
waypoint.x, waypoint.y = waypoint.y, -waypoint.x
elif action == "F":
ship.x += waypoint.x * value
ship.y += waypoint.y * value