Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- """Day 12 of Advent of Code 2020 Solution"""
- from collections import deque
- def direction_io(file_location):
- directions = []
- with open(file_location, "r") as f:
- for line in f.readlines():
- directions.append((line[0], int(line[1:])))
- return directions
- class ShipNavigation:
- COMPASS = {
- "N": complex(0, 1),
- "S": complex(0, -1),
- "E": complex(1, 0),
- "W": complex(-1, 0),
- }
- ROTATION_DIRECTION = {"L": 1, "R": -1}
- def __init__(self, position=complex(0, 0), rotations=deque(["E", "S", "W", "N"])):
- self.position: complex = position
- self.rotations: deque[str] = rotations
- def __add__(self, direction_distance: tuple[str, int]):
- direction, distance = direction_distance
- if direction in "RL":
- self.rotate(direction, distance)
- else:
- if direction == "F":
- direction = self.forward
- self.position = self.position + self.COMPASS[direction] * distance
- return self
- def rotate(self, direction, distance):
- self.rotations.rotate(self.ROTATION_DIRECTION[direction] * distance // 90)
- @property
- def manhattan_distance(self):
- return int(abs(self.position.real) + abs(self.position.imag))
- @property
- def forward(self):
- return self.rotations[0]
- def __str__(self):
- ns_position = "N" if self.position.imag >= 0 else "S"
- ew_position = "E" if self.position.real >= 0 else "W"
- return (
- f"{ns_position} {self.position.imag}, "
- f"{ew_position} {self.position.real}, "
- f"facing {self.forward}, "
- f"Manhattan distance: {self.manhattan_distance}"
- )
- class WaypointShipNavigation(ShipNavigation):
- def __init__(
- self,
- waypoint_position=complex(10, 1),
- ):
- super().__init__(waypoint_position)
- self.ship = ShipNavigation()
- self.offset = None
- self.update_offset()
- def __add__(self, direction_distance):
- direction, distance = direction_distance
- if direction in "NESW":
- super().__add__(direction_distance)
- self.update_offset()
- elif direction in "RL":
- for i in range(distance // 90):
- x = self.offset.real
- y = self.offset.imag
- if direction == "R":
- self.offset = complex(y, -x)
- else:
- self.offset = complex(-y, x)
- self.position = self.ship.position + self.offset
- else: # "F"
- self.ship.position += distance * self.offset
- self.position = self.ship.position + self.offset
- return self
- def update_offset(self):
- self.offset = self.position - self.ship.position
- def part_a(file_location) -> int:
- navigation_instructions = direction_io(file_location)
- current_position = ShipNavigation()
- for direction_and_distance in navigation_instructions:
- current_position += direction_and_distance
- return current_position.manhattan_distance
- def part_b(file_location) -> int:
- navigation_instructions = direction_io(file_location)
- waypoint = WaypointShipNavigation()
- for direction_and_distance in navigation_instructions:
- waypoint += direction_and_distance
- return waypoint.ship.manhattan_distance
- if __name__ == "__main__":
- file_location = r"data\day12.txt"
- print(part_a(file_location))
- print(part_b(file_location))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement