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)))