-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathDay12.py
48 lines (44 loc) · 1.59 KB
/
Day12.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
from helpers.importHelpers import *
def getValidNeighbors(heightMap, current, reversed):
currentX, currentY = current
directions = [(0,1), (0,-1), (1,0), (-1,0)]
for x, y in directions:
x += currentX
y += currentY
if x >= 0 and y >= 0 and x < len(heightMap[0]) and y < len(heightMap):
if reversed:
if heightMap[y][x]+1 >= heightMap[currentY][currentX]:
yield (x, y)
else:
if heightMap[y][x] <= heightMap[currentY][currentX]+1:
yield (x, y)
def bfs(heightMap, start, endFunc, reversed = False):
queue = [start]
visited = set()
cost = {(start): 0}
while queue:
current = queue.pop(0)
if endFunc(current): #endFunc(current) is true, if current is the goal
return cost[current]
for neighbor in getValidNeighbors(heightMap, current, reversed):
if neighbor not in visited or cost[current] + 1 < cost[neighbor]:
cost[neighbor] = cost[current] + 1
queue.append(neighbor)
visited.add(neighbor)
stringInput = getInput()
heightMap = []
chars = "abcdefghijklmnopqrstuvwxyz"
for y, line in enumerate(stringInput.split("\n"), 0):
heightMap.append([])
for x, char in enumerate(line, 0):
match char:
case "S":
start = (x,y)
heightMap[y].append(0) #value of a
case "E":
end = (x,y)
heightMap[y].append(25) #value of z
case _:
heightMap[y].append(chars.index(char))
print("Part 1: ", bfs(heightMap, start, lambda position: position == end))
print("Part 2: ", bfs(heightMap, end, lambda position: heightMap[position[1]][position[0]] == 0, reversed = True))