def __init__(self, data, part="a"): grid = ZGrid(data, on=".", off="#") if part == "b": [z0] = [z for z, v in grid.items() if v == "@"] pos = ("@0", "@1", "@2", "@3") for dz in [0, -1j, 1, 1j, -1]: grid[z0 + dz] = grid.off for p, dz in zip(pos, [-1 - 1j, 1 - 1j, 1 + 1j, -1 + 1j]): grid[z0 + dz] = p else: pos = ("@", ) graph = grid.graph(extra=frozenset(string.ascii_letters).union(pos)) self.all_keys = {k for k in graph.extra if k in string.ascii_lowercase} # map of the other keys that must be acquired before each key is acquired self.obstructions = {k: set() for k in self.all_keys} # precached distances between points of interest self.kdist = {} for k0 in self.all_keys: for p in pos: try: path = nx.shortest_path(graph, graph.extra[p], graph.extra[k0]) except nx.NetworkXNoPath: pass else: break else: raise Exception self.kdist[k0, p] = self.kdist[p, k0] = len(path) - 1 assert path[0] == graph.extra[p] assert path[-1] == graph.extra[k0] for p in path[1:-1]: if p in graph.extra.values(): k1 = grid[p].lower() self.obstructions[k0].add(k1) for k1, k2 in combinations(self.all_keys, 2): z1 = graph.extra[k1] z2 = graph.extra[k2] try: d = nx.shortest_path_length(graph, z1, z2) except nx.NetworkXNoPath: continue self.kdist[k1, k2] = self.kdist[k2, k1] = d state0 = pos, frozenset() AStar.__init__(self, state0, target=None)
""" --- Day 24: Air Duct Spelunking --- https://adventofcode.com/2016/day/24 """ from aoc_wim.zgrid import ZGrid from itertools import combinations from itertools import permutations import networkx as nx from aocd import data grid = ZGrid(data, on=".", off="#") graph = grid.graph(extra="0123456789") distances = {} for a, b in combinations(graph.extra, 2): d = nx.shortest_path_length(graph, graph.extra[a], graph.extra[b]) distances[a, b] = distances[b, a] = d def shortest_path(part="a"): paths = {} for nodes in permutations(graph.extra.keys() - {"0"}): path = "0" + "".join(nodes) if part == "b": path += "0" paths[path] = sum(distances[a, b] for a, b in zip(path, path[1:])) return min(paths.values()) print("part a:", shortest_path(part="a")) print("part b:", shortest_path(part="b"))
""" --- Day 9: Smoke Basin --- https://adventofcode.com/2021/day/9 """ from aocd import data import networkx as nx from aoc_wim.zgrid import ZGrid g = ZGrid(data) bs = sorted(nx.connected_components(g.graph(extra="012345678")), key=len) print("part a:", sum(min([1 + int(g[z]) for z in b]) for b in bs)) print("part b:", len(bs[-1]) * len(bs[-2]) * len(bs[-3]))