|
@@ -0,0 +1,84 @@
|
|
|
|
+import itertools
|
|
|
|
+from math import sin, cos, radians, atan2, sqrt, pi, degrees
|
|
|
|
+
|
|
|
|
+instructions = []
|
|
|
|
+
|
|
|
|
+with open("12.input") as f:
|
|
|
|
+ for line in f.readlines():
|
|
|
|
+ line = line.strip()
|
|
|
|
+ instructions.append((line[0], int(line[1:])))
|
|
|
|
+
|
|
|
|
+myadd = lambda xs,ys: tuple(x + y for x, y in zip(xs, ys))
|
|
|
|
+
|
|
|
|
+def manhattan_distance(pos):
|
|
|
|
+ (x, y) = pos
|
|
|
|
+ return abs(y) + abs(x)
|
|
|
|
+
|
|
|
|
+def move(position, angle, instruction):
|
|
|
|
+ op, arg = instruction
|
|
|
|
+
|
|
|
|
+ if op == 'L':
|
|
|
|
+ angle += arg
|
|
|
|
+ elif op == 'R':
|
|
|
|
+ angle -= arg
|
|
|
|
+ elif op == 'N':
|
|
|
|
+ position = myadd(position, (0, arg))
|
|
|
|
+ elif op == 'S':
|
|
|
|
+ position = myadd(position, (0, -arg))
|
|
|
|
+ elif op == 'E':
|
|
|
|
+ position = myadd(position, (arg, 0))
|
|
|
|
+ elif op == 'W':
|
|
|
|
+ position = myadd(position, (-arg, 0))
|
|
|
|
+ elif op == 'F':
|
|
|
|
+ position = myadd(position, (cos(radians(angle)) * arg, sin(radians(angle)) * arg))
|
|
|
|
+
|
|
|
|
+ return (position, angle)
|
|
|
|
+
|
|
|
|
+position = (0, 0)
|
|
|
|
+angle = 0
|
|
|
|
+
|
|
|
|
+for instruction in instructions:
|
|
|
|
+ (position, angle) = move(position, angle, instruction)
|
|
|
|
+
|
|
|
|
+print("Answer 1: {:0.0f}".format(manhattan_distance(position)))
|
|
|
|
+
|
|
|
|
+def print_vector(vec):
|
|
|
|
+ print("{}, {}".format(vec, degrees(atan2(vec[1], vec[0]))))
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+def rotate(vec, degrees):
|
|
|
|
+ angle = atan2(vec[1], vec[0])
|
|
|
|
+ length = sqrt(vec[0] ** 2 + vec[1] ** 2)
|
|
|
|
+ angle += radians(degrees)
|
|
|
|
+ vec = (cos(angle) * length, sin(angle) * length)
|
|
|
|
+ return vec
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+def move_waypoint(ship_pos, way_pos, instruction):
|
|
|
|
+ op, arg = instruction
|
|
|
|
+
|
|
|
|
+ if op == 'L':
|
|
|
|
+ way_pos = rotate(way_pos, arg)
|
|
|
|
+ elif op == 'R':
|
|
|
|
+ way_pos = rotate(way_pos, -arg)
|
|
|
|
+ elif op == 'N':
|
|
|
|
+ way_pos = myadd(way_pos, (0, arg))
|
|
|
|
+ elif op == 'S':
|
|
|
|
+ way_pos = myadd(way_pos, (0, -arg))
|
|
|
|
+ elif op == 'E':
|
|
|
|
+ way_pos = myadd(way_pos, (arg, 0))
|
|
|
|
+ elif op == 'W':
|
|
|
|
+ way_pos = myadd(way_pos, (-arg, 0))
|
|
|
|
+ elif op == 'F':
|
|
|
|
+ ship_pos = (ship_pos[0] + way_pos[0] * arg, ship_pos[1] + way_pos[1] * arg)
|
|
|
|
+
|
|
|
|
+ return (ship_pos, way_pos)
|
|
|
|
+
|
|
|
|
+ship_pos = (0, 0)
|
|
|
|
+way_pos = (10, 1)
|
|
|
|
+
|
|
|
|
+for instruction in instructions:
|
|
|
|
+ (ship_pos, way_pos) = move_waypoint(ship_pos, way_pos, instruction)
|
|
|
|
+
|
|
|
|
+print("Answer 2: {:0.0f}".format(manhattan_distance(ship_pos)))
|
|
|
|
+
|