Example #1
0
def render(g):
    if isinstance(g, str):
        g = graph(g)
    xs = [int(z.real) for z in g.nodes]
    ys = [int(z.imag) for z in g.nodes]
    x0, x1 = min(xs) - 1, max(xs) + 2
    y0, y1 = min(ys) - 1, max(ys) + 2
    for y in range(y0, y1):
        line = ""
        for x in range(x0, x1):
            z = complex(x, y)
            if z == 0:
                line += "X"
            elif z in g.nodes:
                line += "."
            elif (z - 1, z + 1) in g.edges:
                line += "|"
            elif (z - 1j, z + 1j) in g.edges:
                line += "-"
            elif any(zn in g.nodes for zn in ZGrid.near(z, n=8)):
                line += "#"
            else:
                line += " "
        print(line)
    print()
Example #2
0
    def __init__(self, data, part="a"):
        grid = ZGrid(data, on=".", off="#")
        pos = ("@", )
        if part == "b":
            [z0] = [z for z, v in grid.items() if v == "@"]
            if grid.count_near(z0, val=".", n=8, default=".") == 8:
                pos = ("@0", "@1", "@2", "@3")
                for z in grid.near(z0, n=5):
                    grid[z] = grid.off
                for p, dz in zip(pos, [-1 - 1j, 1 - 1j, 1 + 1j, -1 + 1j]):
                    grid[z0 + dz] = p
        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("nothing possible to do")
            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)
Example #3
0
g = ZGrid(data, transform=int)
a = b = 0
while True:
    b += 1
    n = 0
    flash = []
    for z in g:
        if g[z] == 9:
            g[z] = 0
            flash.append(z)
        else:
            g[z] += 1
    while flash:
        z0 = flash.pop()
        n += 1
        for z in g.near(z0, n=8):
            if g.get(z):
                if g[z] == 9:
                    g[z] = 0
                    flash.append(z)
                else:
                    g[z] += 1
    if b <= 100:
        a += n
    if n == len(g):
        break

print("part a:", a)
print("part b:", b)