aoc/2022/day12.py
2023-04-17 20:18:20 +02:00

104 lines
2.6 KiB
Python
Executable file

#!/bin/python3
import sys
sys.setrecursionlimit(1500)
hmap = list()
with open('day12.txt', 'r') as f:
for line in f:
hmap.append(line.strip())
h = len(hmap)
w = len(hmap[0])
for y in range(h):
for x in range(w):
if hmap[y][x] == 'S':
start = (x, y)
if hmap[y][x] == 'E':
end = (x, y)
def get_elevation(char):
if char == 'S':
return ord('a')
if char == 'E':
return ord('z')
return ord(char)
def get_adjacents(pos):
(x, y) = pos
return [(x-1, y), (x+1, y), (x, y-1), (x, y+1)]
def in_bounds(pos):
(x, y) = pos
return x >= 0 and x < w and y >= 0 and y < h
def get_char(hmap, pos):
(x, y) = pos
return hmap[y][x]
def valid_jump(hmap, pos, adj):
poschar = get_char(hmap, pos)
adjchar = get_char(hmap, adj)
poselev = get_elevation(poschar)
adjelev = get_elevation(adjchar)
return poselev + 1 >= adjelev
best_cost = {}
def find_path(hmap, path, pos):
if get_char(hmap, pos) == 'E':
return [path]
paths = list()
for adj in get_adjacents(pos):
if adj not in path and in_bounds(adj) and valid_jump(hmap, pos, adj):
if adj not in best_cost or best_cost[adj] > len(path):
best_cost[adj] = len(path)
new_path = set.copy(path)
new_path.add(adj)
paths.extend(find_path(hmap, new_path, adj))
return paths
shortest = None
paths = find_path(hmap, set([start]), start)
for path in paths:
if not shortest or len(path) < shortest:
shortest = len(path)
print('part1', shortest - 1)
trail_lengths = {}
def valid_jump2(hmap, pos, adj):
poschar = get_char(hmap, pos)
adjchar = get_char(hmap, adj)
poselev = get_elevation(poschar)
adjelev = get_elevation(adjchar)
return adjelev + 1 >= poselev
def find_trail(hmap, trail, pos):
for adj in get_adjacents(pos):
if adj not in trail and in_bounds(adj) and valid_jump2(hmap, pos, adj):
trail_length = len(trail) + 1
if adj not in trail_lengths or trail_lengths[adj] > trail_length:
trail_lengths[adj] = trail_length
new_trail = list.copy(trail)
new_trail.append(adj)
find_trail(hmap, new_trail, adj)
find_trail(hmap, [end], end)
shortest = None
for y in range(h):
for x in range(w):
if (x, y) in trail_lengths:
if get_elevation(get_char(hmap, (x, y))) == ord('a'):
trail_length = trail_lengths[(x, y)]
if not shortest or trail_length < shortest:
shortest = trail_length
print('part2', shortest - 1)