summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Tom van der Lee <t0m.vd.l33@gmail.com>2022-12-12 10:49:04 +0100
committerGravatar Tom van der Lee <t0m.vd.l33@gmail.com>2022-12-12 10:49:04 +0100
commit126a628b171e2a7d2490290185ab21990b0d9698 (patch)
treebce90696bbc1ed94f96f162f141e36b61a13b5b5
parent0af1b042a29811bc5c850267681dc45469981845 (diff)
download2022-126a628b171e2a7d2490290185ab21990b0d9698.tar.gz
2022-126a628b171e2a7d2490290185ab21990b0d9698.tar.bz2
2022-126a628b171e2a7d2490290185ab21990b0d9698.zip
Day12 [Wip]
-rw-r--r--day12/__init__.py137
-rw-r--r--day12/example.txt5
-rw-r--r--day12/input.txt41
-rw-r--r--day12/test_init.py27
4 files changed, 210 insertions, 0 deletions
diff --git a/day12/__init__.py b/day12/__init__.py
new file mode 100644
index 0000000..52fa2e7
--- /dev/null
+++ b/day12/__init__.py
@@ -0,0 +1,137 @@
1# -*- coding: utf-8 -*-
2import sys
3from abc import ABC
4from math import inf, sqrt, floor
5from typing import List, Tuple, Iterator, Callable, Any
6
7from aoc import BaseAssignment
8
9
10class Map:
11 def __init__(self, map: List[str]):
12 self.map = map
13
14 self.height = len(map)
15 self.width = len(map[0])
16
17 self.start = self.find_unique_position("S")
18 self.end = self.find_unique_position("E")
19
20 def find_unique_position(self, value: str) -> Tuple[int, int]:
21 for y in range(self.height):
22 for x in range(self.width):
23 if self.map[y][x] == value:
24 return x, y
25
26 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)):
28 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 (
33 (dy == y and dx == x)
34 or (dy == y - 1 and dx == x - 1)
35 or (dy == y - 1 and dx == x + 1)
36 or (dy == y + 1 and dx == x - 1)
37 or (dy == y + 1 and dx == x + 1)
38 or (abs(neigbour_elevation - current_elevation) > 1)
39 ):
40 continue
41 yield dx, dy
42
43 def elevation(self, x: int, y: int):
44 character = self.map[y][x]
45
46 match character:
47 case "S":
48 elevation = ord("a")
49 case "E":
50 elevation = ord("z")
51 case _:
52 elevation = ord(character)
53
54 return elevation - 96
55
56
57class Assignment(BaseAssignment, ABC):
58 def distance(self, map: Map, a: Tuple[int, int], b: Tuple[int, int]):
59 distance = abs(map.elevation(*a) - map.elevation(*b))
60
61 if distance > 1:
62 return inf
63
64 return distance
65
66 def heuristic(self, map: Map, a: Tuple[int, int]):
67 dx = abs(map.start[0] - a[0])
68 dy = abs(map.start[1] - a[1])
69 return floor(sqrt(dx**2 + dy**2))
70
71 def a_star(
72 self,
73 map: Map,
74 start: Tuple[int, int],
75 end: Tuple[int, int],
76 distance: Callable[[Tuple[int, int], Tuple[int, int]], int],
77 heuristic: Callable[[Tuple[int, int]], int],
78 ) -> List[Tuple[int, int]]:
79 open = {start}
80 came_from = {}
81
82 g_scores = {start: 0}
83
84 f_scores = {start: heuristic(start)}
85
86 while True:
87 try:
88 current = sorted(
89 [item for item in open], key=lambda item: f_scores.get(item, inf)
90 )[0]
91 except IndexError:
92 raise RuntimeError("No path found")
93
94 if current == end:
95 path = [current]
96
97 while current in came_from:
98 current = came_from[current]
99 path = [current, *path]
100
101 return path
102
103 open.remove(current)
104
105 for neighbour in map.neighbours(*current):
106 g_score = g_scores.get(current, inf) + distance(current, neighbour)
107
108 if g_score < g_scores.get(neighbour, inf):
109 came_from[neighbour] = current
110 g_scores[neighbour] = g_score
111 f_scores[neighbour] = g_score + heuristic(neighbour)
112
113 if neighbour not in open:
114 open.add(neighbour)
115
116
117class AssignmentOne(Assignment):
118 example_result = 31
119
120 def run(self, input: Iterator) -> Any:
121 map = Map(map=list(input))
122
123 print(map.start, map.end)
124
125 path = self.a_star(
126 map,
127 map.start,
128 map.end,
129 distance=lambda a, b: self.distance(map, a, b),
130 heuristic=lambda a: self.heuristic(map, a),
131 )
132
133 return len(path) - 1
134
135
136class AssignmentTwo(Assignment):
137 pass
diff --git a/day12/example.txt b/day12/example.txt
new file mode 100644
index 0000000..86e9cac
--- /dev/null
+++ b/day12/example.txt
@@ -0,0 +1,5 @@
1Sabqponm
2abcryxxl
3accszExk
4acctuvwj
5abdefghi
diff --git a/day12/input.txt b/day12/input.txt
new file mode 100644
index 0000000..7fc8957
--- /dev/null
+++ b/day12/input.txt
@@ -0,0 +1,41 @@
1abcccccccccccccccccccccccccccccccccccccccccccccccccccaaaaacccccccccccccaaaaaaaccccccccccccccccaaaaaaccccccccccccccccccccccccccaaaaacccaaaccccccccccccccccccccccccccccccaaaaa
2abcccccccccaaaccccccccccccaaaccccccccccccccccccccccccaaaaaacccccccccccccaaaaaaaaaaaccaaaaccccaaaaaaacccccccccccccccccccccccccccaaaaaacaaaaccccccccccccccccccccccccccccccaaaa
3abcccccccccaaaaaacccccccccaaaacccccccccccccccccccccccaaaaaaccccccccccccaaaaaaaaaaaccaaaaacccaaaaaacccccccccaaacccccccccccccccaaaaaaaacaaaaccccccccccccccccacccccccccccccaaaa
4abcccccccccaaaaaacccccccccaaaaccccaacccccccccccccccccaaaaaaccccccccccaaaaaaaaaaaaaacaaaaaaccaacaaaccaacccaaaaaaccccccccccccccaaaaaaaacaaaccccccccccaccccaaaccccccccccccaaaaa
5abcccccccaaaaaaaccccccccccaaaacccaaaaccccccccccccaaccccaaacccccccaaacaaaaaaaaaccccccaaaaaacccccaaaccaacccaaaaaacccccccccccccccccaaccccccccccccccccaaacccaaaccccccccccccaaaca
6abcccccccaaaaaaacccccccaaacccccccaaaacccccccaaccaaaccccccccccccaaaaacaaaaaaaaaccccccaaaaaccccccccaaaaaaaacaaaaaccaacaaccccccccccaaccccccccccccccccaaaaaaaaaccccccccccccccccc
7abcccccccccaaaaaaccaaccaaacccccccaaaacccccccaaaaaaaccccccccccccaaaaaaccccaaaaaacccccccaaaccccccccaaaaaaaaaaaaacccaaaaacccccccaaaccccccccccccccccccaaaaaaaackcccccccccccccccc
8abcccccccccaaaaaaccaaaaaaaccccccccccccccccccaaaaaacccccccccccccaaaaaaccccaaaaaaccccccccccccccccccccaaaaccaaaaaccccaaaaaccccccaaaaaccccaaaaaccccccccaaaajjkkkkkccccccaacccccc
9abcccccccccaaccccccaaaaaaccccccccccccccccccccaaaaaaaaccccccccccaaaaacccaaaacaaccccccccccccccccccccaaaaaccccccccccaaaaaacccccaaaaaaccccaaaaaccciijjjjjjjjjkkkkkkccaaaaaaccccc
10abcaaaccccccccccccccaaaaaaaaccccccccccccccccaaaaaaaaacccccccccccaaaacccaaaccaaccccccccccccccccccccaacaaacccccccccaaaacccccccaaaaaacccaaaaaaciiiijjjjjjjjjoopkkkkcaaaaacccccc
11abaaaacccccccccccccaaaaaaaaaccccccccccccccccaaaaaaaacccccccccccccccccccaaaaaaaccccaccaccccccccccccacccaacccccccccccaaccccccccaaaaacccaaaaaaiiiiiijjjjjjoooppppkkcaaaaaaacccc
12abaaaaaccccccccccccaaaaaaaaccccccccccccccccaaaaaaaccccccccccccccccccccccaaaaaaccccaaaacccccccccccccccccccccccccccccccccccccccaaaaccccaaaaaiiiinnnoooooooooppppkkkaaaaaaacccc
13abaaaaacccccccccccaaaaaaaccccccccccccccccccccccaaacccccccccccccccccccaaaaaaaacccccaaaaccccccccccccaaccaacccccaccccacccccccccccccccccccaaaciiinnnnoooooooouupppkkkaaaaaaacccc
14abaaaaccccccccccccccccaaaccccccccccccccccccccccaaacccccccaaccccccccccaaaaaaaaacccaaaaaacccccccccccaaaaaaccccaaaaaaaacccccccccccccaaccccccciiinnnntttooouuuuupppiiacaaacccccc
15abaaaacccccccccccccccccaaccccccccccccccccccccccccccccccaaaacacccccccccaaaaaaaacccaaaaaacccccccccccaaaaaccccccaaaaaacccccccccccaaaaaacccccciinnnttttuuuuuuuuuuppiiccaaacccccc
16abcccccccccccccccccccccccccccccccccccccccccccccccccccccaaaaaacccccccccccaaaaaaaccccaacccccaaccccccaaaaaacccccaaaaaacccccccccccaaaaaccccccciinnntttttuuuuxyuuuppiiicccccccccc
17abccccccccccccccccccccccccccccccccccccaaacccccccaaccccccaaaaccccccccccccaaccccccccccccccccaacaaacaaaaaaaacccaaaaaaaaccccccccccaaaaaaaccccchinnnttxxxxuuxyyyuuppiiiiccccccccc
18abccccccccccccccccccccccccccccccccccccaaaaaaccccaaacccccaaaaccccccccccccaaccccccccccccccccaaaaaccaaaaaaaaccaaaaaaaaaaccccccccaaaaaaaaccccchhhnnttxxxxxxxyyuvppppiiiccccccccc
19abccccccccccccccccccccccccccccccccccaaaaaaaaaaccaaaaaaacacaacccccccccccccccccaaaccccccccaaaaaaccccccaacccccaaaaaaaaaaccccccccaaaaaaaaccccchhhnntttxxxxxxyyvvvppqqiiicccccccc
20abccccccccccccccccccccccccccccaacaccaaaaaaaaaaaaaaaaaaacccccccccccccccccccccaaaaaaccccccaaaaaaacccccaacccccaccaaaaacacccccccccacaaaccccccchhhnnnttxxxxxyyyvvvvqqqqiiiccccccc
21SbccccccccccccccccccccccccccccaaaaccaaaaaaacaaaaaaaaaaccccccccccccccccccccccaaaaaaccccccccaaaaaaccccccccccccccaaaaccccccccccccccaaacccccchhhmmmtttxxxEzzyyyyvvvqqqqiiccccccc
22abcccccccccccccccccccccccccccaaaaaccccaaaaaccaaaaaaaaacccccccccccccccaaaaaccaaaaaaccccccccaaccaacccccccccccccccaacccccccaaaaccccccccccccchhhmmmtttxxxyyyyyyyyvvvqqqjjjcccccc
23abcccaaacccccccccccccccccccccaaaaaacccaacaaaaaaaaaaaaacccccccccccccccaaaaacccaaaaaccccccccaacccccccccccccccccccccccccccaaaaacccccccccccchhhmmmttsxxyyyyyyyyvvvvvqqqjjjcccccc
24abcccaaaaaacccaacaaccccccccccacaaaacccaacccaaaaaaaaaaaacccccccccccccaaaaaacccaacaaccccccccccccccccccccccccccccccccaacccaaaaaaccccccccccchhhmmmssxxwwwwyyywvvvvvqqqjjjjcccccc
25abccaaaaaaacccaaaaaccccccccccccaaccccccccccaaaaaaaccaaccccccccccccccaaaaaacccccccccccccccccccccccccccccccccccaaccaaacccaaaaaacccccccaaachhhmmssswwwwwwyyywvvqqqqqqjjjccccccc
26abcaaaaaaacccccaaaaacccccccccccccccccccccccccccaaaccccccccccccccccccaaaaaacccccccccccaaccccaaccccccccccccccccaaacaaacccaaaaaacccccccaaacgggmmsssswwwswwyywwrrqqqjjjjcccccccc
27abcaaaaaaaccccaaaaaacccccccccccccccccccccccaaccaaaccccccccccccccccccccaaccccccccccccaaccccaaaacccccccccccccccaaaaaaccccccaacccccccaacaaagggmmmssssssswwwwwwrrqjjjjjddccccccc
28abcccaaaaaacccaaaacccccccccccccccccccccccccaaacaaccccccccccccccccccccccccccccccccaaaaacaacaaaaccccccccccccccccaaaaaaaaccccccccccccaaaaaagggmmmmssssssswwwwrrrkjjjjddddcccccc
29abcccaaaaaacccccaaccccccccccccccccccccccccccaaaaaccccccccccccccccccccccccccccccccaaaaaaaacaaaacaaccccccaaccaaaaaaaaaaacccccccccccccaaaaaggggmmmmllllsrrwwwrrkkkjdddddaaacccc
30abcccaaaccccccccccccaacccccccccccccccccccccaaaaaaccccccccccccccccccccccccccccccccccaaaaacccccccaaaaaaccaaaaaaaaaaaaaacccccccccccccccaaaaaggggmmllllllrrrrrrrkkkdddddaaaccccc
31abccccaaaaaaccccccccaacaaaccccccccacccaaccaaaaaaaaccccccccccaaaccccccaacccccccccccaaaaaccccccccaaaaacccaaaaaaaaaaaaccccccccccccccccaaacaacggggggflllllrrrrrrkkddddaaaaaccccc
32abccccaaaaacccccccccaaaaacccccccccaaaaaaccaaaaaaaaccccccccccaaacacccaaaaccccccccccaacaaacccccaaaaaaccccaaaaaaaccaaacccccccccccccccccaacccccggggffffllllrrrrkkkdddaaaaaaacccc
33abccaaaaaaacccccccaaaaaaccccccccccaaaaaccccccaacccccaaccccaacaaaaaccaaaacccccccaaccccaaccccccaaaaaaaccaaaaaaaaccaaaccccccccccccccccccaaaccccccgffffflllkkkkkkeedaaaaaaaacccc
34abccaaaaaaacccccccaaaaaaacccccccccaaaaaacccccaacccccaaacccaaaaaaaaccaaaacccaaaaacccccccccccccccaaaaaacaaaaaaaacccccccccccccccccccccccaaaacaacccccffffllkkkkkeeedccaaaaaacccc
35abccccaaaaaaccccccccaaaaaacccccccaaaaaaaacccccaaccccaaaaaaaaaaaaccccccccccaaaaaaaacccccccccccccaaccaaccccaaaccccccaacccccccccccccccccaaaaaaaccccccfffffkkkkeeeecccaacccccccc
36abccccaaccaaccccccccaaccaacccccccaaaaaaaacccccaaccaaaaaaaaccaaaaacccccccccaaaaaaaaccccccccccaacaaccccccccaaccccaacaaaccccaacccccccccccaaaaaaccccccaafffeeeeeeecccccccccccccc
37abccccaaccccccccccccaaccccccccccccccaacccccaaaaaaaaaaaaaaacaaacaaaaaaacaccaaaaaaacccccccaaacaacccccccccccccccccaaaaaccccaaaacccccccaaaaaaaaccccccaaaaffeeeeeeeccccccccccccca
38abacccccccccccccaaacccccccccccccccccaacccccaaaaaaaaaaaaaacccaaccaaaaaaaaaaaaaccaaacccccccaaaaaccccccccccccccccccaaaaaaccaaaacccccccaaaaaaaaaccccccaaacceeeeeccccccccccccccaa
39abaaccccccccccaaaaaacccccccccccccccccccccccccaaaacccaaaaaaccccccaaaaaaaaaaaaaaaaaaaccccccaaaaaaacccaaaccccccccaaaaaaaaccaaaaccccccccaaaaaaaaccccccccccccaaacccccccccccaaacaa
40abaaccccccccccaaaaaacccccccccccccccccccccccccaaaaacaaaaaaaccccccaaaaaaaaaaaaaaaaaaccccccaaaaaaaaccccaaaaccccccaaaaacaaccccccccccccccccaaaaaaacccccccccccacacccccccccccaaaaaa
41abacccccccccccaaaaaaccccccccccccccccccccccccaaaaaacaaaccaaccccccaaaaaaccaaaaaaaaccccccccaaaaaaaaccaaaaaacccccccccaaaccccccccccccccccccaacccccccccccccccccccccccccccccccaaaaa
diff --git a/day12/test_init.py b/day12/test_init.py
new file mode 100644
index 0000000..f721d56
--- /dev/null
+++ b/day12/test_init.py
@@ -0,0 +1,27 @@
1# -*- coding: utf-8 -*-
2from day12 import Map
3
4
5class TestMap:
6 def test_neighbours(self):
7
8 map_input = ["".join([str(i) for i in range(8)]) for _ in range(5)]
9
10 map = Map(map=map_input)
11
12 assert set(map.neighbours(0, 0)) == {
13 (0, 1),
14 (1, 0),
15 }
16
17 assert set(map.neighbours(0, 4)) == {
18 (0, 3),
19 (1, 4),
20 }
21
22 assert set(map.neighbours(1, 1)) == {
23 (0, 1),
24 (1, 0),