Files
advent-of-code/2022/12/part2
2022-12-13 00:13:15 +00:00

69 lines
1.7 KiB
Python
Executable File

#!/usr/bin/env python
import math
from collections import defaultdict
MAP = []
END = (0, 0)
def possible(x, y):
global MAP
threshold = MAP[y][x] + 1 # Can't go higher than this, can always go lower
points = [(x-1,y),(x+1,y),(x,y-1),(x,y+1)]
out = []
for (x,y) in points:
if x < 0 or y < 0:
continue
if len(MAP) < y+1 or len(MAP[y]) < x+1:
continue
if MAP[y][x] > threshold:
continue
out.append((x,y))
return out
with open('input') as f:
for y, line in enumerate(f):
row = []
for x, byte in enumerate(line.rstrip()):
if byte == 'S':
byte = 'a'
elif byte == 'E':
byte = 'z'
END = (x,y)
row.append(ord(byte) - ord('a'))
MAP.append(row)
def search(start):
distances = defaultdict(lambda: math.inf)
distances[start] = 0
visited = set([])
queue = [start]
while len(queue) > 0:
pos = queue.pop(0)
visited.add(pos)
for neighbour in possible(*pos):
if neighbour == END:
return distances[pos] + 1
if distances[neighbour] > distances[pos] + 1:
distances[neighbour] = distances[pos] + 1
if neighbour not in visited and neighbour not in queue:
queue.append(neighbour)
return None # Some start positions may not have a valid path
results = []
for y, row in enumerate(MAP):
for x, height in enumerate(row):
if height == 0:
result = search((x,y))
if result != None:
results.append(result)
print(sorted(results)[0])