63 lines
1.9 KiB
Python
Executable File
63 lines
1.9 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
import sys
|
|
import numpy as np
|
|
|
|
dirs = 'WSEN'
|
|
|
|
def tpl(l): # get nice tuple from line
|
|
return l[0], int(l[1:])
|
|
|
|
def turn1(course, side, deg):
|
|
return dirs[(dirs.index(course) + (1 if side == 'L' else -1) * deg // 90 + 4) % 4]
|
|
|
|
def turn(course, side, deg): # complex rotation
|
|
theta = (1j if side == 'L' else -1j) ** (deg // 90)
|
|
z = complex(*course)
|
|
newz = z * theta
|
|
return np.asarray((newz.real, newz.imag), dtype=int)
|
|
|
|
def mturn(course, side, deg): # matrix rotation
|
|
rot = [np.asarray(m).reshape((2, 2)).T for m in
|
|
((1, 0, 0, 1), # not used
|
|
(0, -1, 1, 0),
|
|
(-1, 0, 0, -1),
|
|
(0, 1, -1, 0))]
|
|
index = (360 - deg if side == 'R' else deg) // 90
|
|
return(course.dot(rot[index]))
|
|
|
|
def tot(course, l):
|
|
return sum(d for c, d in l if c == course)
|
|
|
|
def shift(d, n):
|
|
return np.asarray(((-1, 0), (0, -1), (1, 0), (0, 1))[dirs.index(d)]) * n
|
|
|
|
fn = sys.argv[1] if len(sys.argv) > 1 else 'input12'
|
|
with open(fn) as f:
|
|
|
|
lines = [l.strip() for l in f.readlines()]
|
|
instr = [tpl(l) for l in lines]
|
|
|
|
new = []
|
|
course = 'E'
|
|
for a,b in instr:
|
|
if a in 'LR':
|
|
course = turn1(course, a, b)
|
|
elif a == 'F': # no one else probably did it this way
|
|
new += (course, b), # simply replace all Fx with [WSEN]x as appropriate
|
|
else: # (by "replace" i mean make a new instruction list)
|
|
new += (a, b),
|
|
dist = abs(tot('E', new) - tot('W', new)) + abs(tot('S', new) - tot('N', new))
|
|
print(dist)
|
|
|
|
waypoint = np.asarray((10, 1), dtype=int)
|
|
pos = np.asarray((0, 0), dtype=int)
|
|
for a,b in instr:
|
|
if a in 'LR':
|
|
waypoint = turn(waypoint, a, b)
|
|
elif a == 'F':
|
|
pos += waypoint * b
|
|
else:
|
|
waypoint += shift(a, b)
|
|
dist = sum(abs(x) for x in pos)
|
|
print(dist)
|