75 lines
2.4 KiB
Python
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()
|