aoc2020/day12.py

75 lines
2.4 KiB
Python

import aoclib
DAY = 12
TEST_SOLUTION_PART1 = 25
TEST_SOLUTION_PART2 = 286
FACING = ['N', 'E', 'S', 'W']
class Ship:
def __init__(self, waypoint_mode=False, posShipX=0, posShipY=0, posWaypointX=0, posWaypointY=0, facing=0):
self.pos = [
{
'x': posShipX,
'y': posShipY
},
{
'x': posWaypointX,
'y': posWaypointY
}
]
self.waypoint_mode = waypoint_mode
self.facing = facing
def move(self, direction, distance):
if direction == 'F':
if self.waypoint_mode:
self.pos[0]['x'] += self.pos[1]['x'] * distance
self.pos[0]['y'] += self.pos[1]['y'] * distance
return
else:
direction = FACING[self.facing]
if direction == 'N':
self.pos[self.waypoint_mode]['y'] -= distance
elif direction == 'S':
self.pos[self.waypoint_mode]['y'] += distance
elif direction == 'E':
self.pos[self.waypoint_mode]['x'] += distance
elif direction == 'W':
self.pos[self.waypoint_mode]['x'] -= distance
elif direction == 'R':
if not self.waypoint_mode:
self.facing = (self.facing + int(distance / 90)) % 4
else:
for i in range(int(distance / 90)):
self.pos[1]['x'], self.pos[1]['y'] = -self.pos[1]['y'], self.pos[1]['x']
elif direction == 'L':
if not self.waypoint_mode:
self.facing = (self.facing - int(distance / 90)) % 4
else:
for i in range(int(distance / 90)):
self.pos[1]['x'], self.pos[1]['x'] = self.pos[1]['y'], -self.pos[1]['x']
def getManhattanDistance(self, startX=0, startY=0):
return abs(self.pos[0]['x'] + startX) + abs(self.pos[0]['y'] + startY)
def part1(test_mode=False):
my_input = aoclib.getInputAsArray(day=DAY, test=test_mode)
ship = Ship(facing=1)
for instruction in my_input:
ship.move(instruction[0], int(instruction[1:]))
return ship.getManhattanDistance()
def part2(test_mode=False):
my_input = aoclib.getInputAsArray(day=DAY, test=test_mode)
ship = Ship(waypoint_mode=True, posWaypointX=10, posWaypointY=-1, facing=1)
for instruction in my_input:
ship.move(instruction[0], int(instruction[1:]))
return ship.getManhattanDistance()