Skip to content

Commit c21d7eb

Browse files
committed
Added day 2018-22
1 parent f622916 commit c21d7eb

File tree

1 file changed

+137
-0
lines changed

1 file changed

+137
-0
lines changed

2018/22-Mode Maze.py

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
# -------------------------------- Input data ---------------------------------------- #
2+
import os, pathfinding
3+
4+
test_data = {}
5+
6+
test = 1
7+
test_data[test] = {
8+
"input": """depth: 510
9+
target: 10,10""",
10+
"expected": ["114", "45"],
11+
}
12+
13+
test = "real"
14+
input_file = os.path.join(
15+
os.path.dirname(__file__),
16+
"Inputs",
17+
os.path.basename(__file__).replace(".py", ".txt"),
18+
)
19+
test_data[test] = {
20+
"input": open(input_file, "r+").read().strip(),
21+
"expected": ["6256", "Unknown"],
22+
}
23+
24+
# -------------------------------- Control program execution ------------------------- #
25+
26+
case_to_test = "real"
27+
part_to_test = 2
28+
29+
# -------------------------------- Initialize some variables ------------------------- #
30+
31+
puzzle_input = test_data[case_to_test]["input"]
32+
puzzle_expected_result = test_data[case_to_test]["expected"][part_to_test - 1]
33+
puzzle_actual_result = "Unknown"
34+
35+
36+
# -------------------------------- Actual code execution ----------------------------- #
37+
38+
_, depth = puzzle_input.splitlines()[0].split(" ")
39+
_, target = puzzle_input.splitlines()[1].split(" ")
40+
41+
depth = int(depth)
42+
max_x, max_y = map(int, target.split(","))
43+
target = max_x - 1j * max_y
44+
45+
geological = {0: 0}
46+
erosion = {0: 0}
47+
for x in range(max_x + 1):
48+
geological[x] = x * 16807
49+
erosion[x] = (geological[x] + depth) % 20183
50+
for y in range(max_y + 1):
51+
geological[-1j * y] = y * 48271
52+
erosion[-1j * y] = (geological[-1j * y] + depth) % 20183
53+
54+
for x in range(1, max_x + 1):
55+
for y in range(1, max_y + 1):
56+
geological[x - 1j * y] = (
57+
erosion[x - 1 - 1j * y] * erosion[x - 1j * (y - 1)]
58+
) % 20183
59+
erosion[x - 1j * y] = (geological[x - 1j * y] + depth) % 20183
60+
61+
geological[target] = 0
62+
erosion[target] = 0
63+
64+
terrain = {x: erosion[x] % 3 for x in erosion}
65+
66+
if part_to_test == 1:
67+
puzzle_actual_result = sum(terrain.values())
68+
69+
else:
70+
neither, climbing, torch = 0, 1, 2
71+
rocky, wet, narrow = 0, 1, 2
72+
73+
# Override the neighbors function
74+
def neighbors(self, vertex):
75+
north = (0, 1)
76+
south = (0, -1)
77+
west = (-1, 0)
78+
east = (1, 0)
79+
directions_straight = [north, south, west, east]
80+
81+
neighbors = {}
82+
for dir in directions_straight:
83+
target = (vertex[0] + dir[0], vertex[1] + dir[1], vertex[2])
84+
if target in self.vertices:
85+
neighbors[target] = 1
86+
for tool in (neither, climbing, torch):
87+
target = (vertex[0], vertex[1], tool)
88+
if target in self.vertices and tool != vertex[1]:
89+
neighbors[target] = 7
90+
91+
return neighbors
92+
93+
# Add some coordinates around the target
94+
padding = 10 if case_to_test == 1 else 50
95+
for x in range(max_x, max_x + padding):
96+
geological[x] = x * 16807
97+
erosion[x] = (geological[x] + depth) % 20183
98+
for y in range(max_y, max_y + padding):
99+
geological[-1j * y] = y * 48271
100+
erosion[-1j * y] = (geological[-1j * y] + depth) % 20183
101+
for x in range(1, max_x + padding):
102+
for y in range(1, max_y + padding):
103+
if x - 1j * y in geological:
104+
continue
105+
geological[x - 1j * y] = (
106+
erosion[x - 1 - 1j * y] * erosion[x - 1j * (y - 1)]
107+
) % 20183
108+
erosion[x - 1j * y] = (geological[x - 1j * y] + depth) % 20183
109+
110+
terrain = {x: erosion[x] % 3 for x in erosion}
111+
del erosion
112+
del geological
113+
114+
# Then run pathfinding algo
115+
pathfinding.WeightedGraph.neighbors = neighbors
116+
vertices = [
117+
(x.real, x.imag, neither) for x in terrain if terrain[x] in (wet, narrow)
118+
]
119+
vertices += [
120+
(x.real, x.imag, climbing) for x in terrain if terrain[x] in (rocky, wet)
121+
]
122+
vertices += [
123+
(x.real, x.imag, torch) for x in terrain if terrain[x] in (rocky, narrow)
124+
]
125+
graph = pathfinding.WeightedGraph(vertices)
126+
127+
graph.dijkstra((0, 0, torch), (max_x, -max_y, torch))
128+
129+
puzzle_actual_result = graph.distance_from_start[(max_x, -max_y, torch)]
130+
131+
# 979 is too high
132+
133+
134+
# -------------------------------- Outputs / results --------------------------------- #
135+
136+
print("Expected result : " + str(puzzle_expected_result))
137+
print("Actual result : " + str(puzzle_actual_result))

0 commit comments

Comments
 (0)