summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--day12/__init__.py47
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
57class Assignment(BaseAssignment, ABC): 60class 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
136class AssignmentTwo(Assignment): 137class 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]