From b3c49e5353e3911aed20aef1a267643d3f9f14f8 Mon Sep 17 00:00:00 2001 From: Stefan Harmuth Date: Sat, 12 Dec 2020 11:20:30 +0100 Subject: [PATCH] day12: it's a little bit slower, but I like the cleaner code --- day12.py | 104 ++++++++++++++++++++++++++----------------------------- 1 file changed, 50 insertions(+), 54 deletions(-) diff --git a/day12.py b/day12.py index 1acd333..9b0cdc4 100644 --- a/day12.py +++ b/day12.py @@ -6,73 +6,69 @@ TEST_SOLUTION_PART2 = 286 FACING = ['N', 'E', 'S', 'W'] -def move(instruction, posX, posY, facing): - where = instruction[0] - dist = int(instruction[1:]) +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 - if where == 'F': - where = 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 where == 'N': - posY -= dist - elif where == 'S': - posY += dist - elif where == 'E': - posX += dist - elif where == 'W': - posX -= dist - elif where == 'R': - facing = (facing + int(dist / 90)) % 4 - elif where == 'L': - facing = (facing - int(dist / 90)) % 4 + 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'] - return posX, posY, facing + 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) - posX = 0 - posY = 0 - face = 1 + ship = Ship(facing=1) for instruction in my_input: - posX, posY, face = move(instruction, posX, posY, face) + ship.move(instruction[0], int(instruction[1:])) - return abs(posX) + abs(posY) - - -def moveWaypoint(instruction, posShipX, posShipY, posWaypointX, posWaypointY): - where = instruction[0] - dist = int(instruction[1:]) - - if where == 'F': - posShipX += posWaypointX * dist - posShipY += posWaypointY * dist - elif where == 'N': - posWaypointY -= dist - elif where == 'S': - posWaypointY += dist - elif where == 'E': - posWaypointX += dist - elif where == 'W': - posWaypointX -= dist - elif where == 'R': - for i in range(int(dist / 90)): - posWaypointX, posWaypointY = -posWaypointY, posWaypointX - elif where == 'L': - for i in range(int(dist / 90)): - posWaypointX, posWaypointY = posWaypointY, -posWaypointX - - return posShipX, posShipY, posWaypointX, posWaypointY + return ship.getManhattanDistance() def part2(test_mode=False): my_input = aoclib.getInputAsArray(day=DAY, test=test_mode) - posShipX = 0 - posShipY = 0 - posWaypointX = 10 - posWaypointY = -1 + ship = Ship(waypoint_mode=True, posWaypointX=10, posWaypointY=-1, facing=1) for instruction in my_input: - posShipX, posShipY, posWaypointX, posWaypointY = moveWaypoint(instruction, posShipX, posShipY, posWaypointX, posWaypointY) + ship.move(instruction[0], int(instruction[1:])) - return abs(posShipX) + abs(posShipY) + return ship.getManhattanDistance()