diff options
Diffstat (limited to 'day12/__init__.py')
| -rw-r--r-- | day12/__init__.py | 47 |
1 files changed, 34 insertions, 13 deletions
diff --git a/day12/__init__.py b/day12/__init__.py index 52fa2e7..55545f7 100644 --- a/day12/__init__.py +++ b/day12/__init__.py | |||
| @@ -14,28 +14,31 @@ class Map: | |||
| 14 | self.height = len(map) | 14 | self.height = len(map) |
| 15 | self.width = len(map[0]) | 15 | self.width = len(map[0]) |
| 16 | 16 | ||
| 17 | self.start = self.find_unique_position("S") | 17 | try: |
| 18 | self.end = self.find_unique_position("E") | 18 | self.start = next(self.find_position("S")) |
| 19 | except StopIteration: | ||
| 20 | self.start = (0, 0) | ||
| 19 | 21 | ||
| 20 | def find_unique_position(self, value: str) -> Tuple[int, int]: | 22 | try: |
| 23 | self.end = next(self.find_position("E")) | ||
| 24 | except StopIteration: | ||
| 25 | self.start = (0, 0) | ||
| 26 | |||
| 27 | def find_position(self, value: str) -> Iterator[Tuple[int, int]]: | ||
| 21 | for y in range(self.height): | 28 | for y in range(self.height): |
| 22 | for x in range(self.width): | 29 | for x in range(self.width): |
| 23 | if self.map[y][x] == value: | 30 | if self.map[y][x] == value: |
| 24 | return x, y | 31 | yield x, y |
| 25 | 32 | ||
| 26 | def neighbours(self, x: int, y: int) -> Iterator[Tuple[int, int]]: | 33 | def neighbours(self, x: int, y: int) -> Iterator[Tuple[int, int]]: |
| 27 | for dy in range(max(0, y - 1), min(self.height, y + 2)): | 34 | for dy in range(max(0, y - 1), min(self.height, y + 2)): |
| 28 | for dx in range(max(0, x - 1), min(self.width, x + 2)): | 35 | for dx in range(max(0, x - 1), min(self.width, x + 2)): |
| 29 | current_elevation = self.elevation(x, y) | ||
| 30 | neigbour_elevation = self.elevation(dx, dy) | ||
| 31 | |||
| 32 | if ( | 36 | if ( |
| 33 | (dy == y and dx == x) | 37 | (dy == y and dx == x) |
| 34 | or (dy == y - 1 and dx == x - 1) | 38 | or (dy == y - 1 and dx == x - 1) |
| 35 | or (dy == y - 1 and dx == x + 1) | 39 | or (dy == y - 1 and dx == x + 1) |
| 36 | or (dy == y + 1 and dx == x - 1) | 40 | or (dy == y + 1 and dx == x - 1) |
| 37 | or (dy == y + 1 and dx == x + 1) | 41 | or (dy == y + 1 and dx == x + 1) |
| 38 | or (abs(neigbour_elevation - current_elevation) > 1) | ||
| 39 | ): | 42 | ): |
| 40 | continue | 43 | continue |
| 41 | yield dx, dy | 44 | yield dx, dy |
| @@ -56,12 +59,12 @@ class Map: | |||
| 56 | 59 | ||
| 57 | class Assignment(BaseAssignment, ABC): | 60 | class Assignment(BaseAssignment, ABC): |
| 58 | def distance(self, map: Map, a: Tuple[int, int], b: Tuple[int, int]): | 61 | def distance(self, map: Map, a: Tuple[int, int], b: Tuple[int, int]): |
| 59 | distance = abs(map.elevation(*a) - map.elevation(*b)) | 62 | distance = map.elevation(*b) - map.elevation(*a) |
| 60 | 63 | ||
| 61 | if distance > 1: | 64 | if distance > 1: |
| 62 | return inf | 65 | return inf |
| 63 | 66 | ||
| 64 | return distance | 67 | return 1 |
| 65 | 68 | ||
| 66 | def heuristic(self, map: Map, a: Tuple[int, int]): | 69 | def heuristic(self, map: Map, a: Tuple[int, int]): |
| 67 | dx = abs(map.start[0] - a[0]) | 70 | dx = abs(map.start[0] - a[0]) |
| @@ -120,8 +123,6 @@ class AssignmentOne(Assignment): | |||
| 120 | def run(self, input: Iterator) -> Any: | 123 | def run(self, input: Iterator) -> Any: |
| 121 | map = Map(map=list(input)) | 124 | map = Map(map=list(input)) |
| 122 | 125 | ||
| 123 | print(map.start, map.end) | ||
| 124 | |||
| 125 | path = self.a_star( | 126 | path = self.a_star( |
| 126 | map, | 127 | map, |
| 127 | map.start, | 128 | map.start, |
| @@ -134,4 +135,24 @@ class AssignmentOne(Assignment): | |||
| 134 | 135 | ||
| 135 | 136 | ||
| 136 | class AssignmentTwo(Assignment): | 137 | class AssignmentTwo(Assignment): |
| 137 | pass | 138 | example_result = 29 |
| 139 | |||
| 140 | def run(self, input: Iterator) -> Any: | ||
| 141 | map = Map(list(input)) | ||
| 142 | lengths = [] | ||
| 143 | |||
| 144 | for a in map.find_position("a"): | ||
| 145 | try: | ||
| 146 | path = self.a_star( | ||
| 147 | map, | ||
| 148 | a, | ||
| 149 | map.end, | ||
| 150 | distance=lambda a, b: self.distance(map, a, b), | ||
| 151 | heuristic=lambda a: self.heuristic(map, a), | ||
| 152 | ) | ||
| 153 | |||
| 154 | lengths.append(len(path) - 1) | ||
| 155 | except RuntimeError: | ||
| 156 | continue | ||
| 157 | |||
| 158 | return sorted(lengths)[0] | ||
