day12: it's a little bit slower, but I like the cleaner code

This commit is contained in:
Stefan Harmuth 2020-12-12 11:20:30 +01:00
parent 38032fbb6e
commit b3c49e5353

104
day12.py
View File

@ -6,73 +6,69 @@ TEST_SOLUTION_PART2 = 286
FACING = ['N', 'E', 'S', 'W'] FACING = ['N', 'E', 'S', 'W']
def move(instruction, posX, posY, facing): class Ship:
where = instruction[0] def __init__(self, waypoint_mode=False, posShipX=0, posShipY=0, posWaypointX=0, posWaypointY=0, facing=0):
dist = int(instruction[1:]) self.pos = [
{
'x': posShipX,
'y': posShipY
},
{
'x': posWaypointX,
'y': posWaypointY
}
]
self.waypoint_mode = waypoint_mode
self.facing = facing
if where == 'F': def move(self, direction, distance):
where = FACING[facing] 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': if direction == 'N':
posY -= dist self.pos[self.waypoint_mode]['y'] -= distance
elif where == 'S': elif direction == 'S':
posY += dist self.pos[self.waypoint_mode]['y'] += distance
elif where == 'E': elif direction == 'E':
posX += dist self.pos[self.waypoint_mode]['x'] += distance
elif where == 'W': elif direction == 'W':
posX -= dist self.pos[self.waypoint_mode]['x'] -= distance
elif where == 'R': elif direction == 'R':
facing = (facing + int(dist / 90)) % 4 if not self.waypoint_mode:
elif where == 'L': self.facing = (self.facing + int(distance / 90)) % 4
facing = (facing - int(dist / 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): def part1(test_mode=False):
my_input = aoclib.getInputAsArray(day=DAY, test=test_mode) my_input = aoclib.getInputAsArray(day=DAY, test=test_mode)
posX = 0 ship = Ship(facing=1)
posY = 0
face = 1
for instruction in my_input: 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) return ship.getManhattanDistance()
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
def part2(test_mode=False): def part2(test_mode=False):
my_input = aoclib.getInputAsArray(day=DAY, test=test_mode) my_input = aoclib.getInputAsArray(day=DAY, test=test_mode)
posShipX = 0 ship = Ship(waypoint_mode=True, posWaypointX=10, posWaypointY=-1, facing=1)
posShipY = 0
posWaypointX = 10
posWaypointY = -1
for instruction in my_input: 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()