Files
aocpy/2016/d24.py
2024-05-20 20:00:34 -04:00

62 lines
1.4 KiB
Python

from collections import deque, defaultdict
from itertools import permutations
from lib import Grid2D, INF
def shortest_path(grid, start, end):
seen = set()
open = deque([(start, 0)])
while open:
current, steps = open.popleft()
if current in seen:
continue
seen.add(current)
if current == end:
return steps
for nb in grid.neighbors_ort(current):
if grid[nb] == "#":
continue
open.append((nb, steps + 1))
return None
def solve(data, part_2=False):
g = Grid2D(data)
# g.print()
start = g.find("0")[0]
points = g.find_not("#.")
shortest = defaultdict(defaultdict)
for i in range(len(points)):
for j in range(i + 1, len(points)):
a, b = points[i], points[j]
s = shortest_path(g, a, b)
assert s is not None
shortest[a][b] = s
shortest[b][a] = s
# Brute force all combinations.
points.remove(start)
dmin = INF
for p in permutations(points):
d = 0
d += shortest[start][p[0]]
for i in range(len(p) - 1):
d += shortest[p[i]][p[i + 1]]
if part_2:
d += shortest[p[-1]][start]
dmin = min(d, dmin)
print(dmin)
return
def main():
data = open(0).read().strip()
solve(data)
solve(data, True)
if __name__ == "__main__":
main()