示例#1
0
def part_a(data):
    seen = set()
    grid = ZGrid(data)
    while True:
        k = tuple(grid.items())
        if k in seen:
            return sum(2**i for i, glyph in enumerate(grid.values())
                       if glyph == "#")
        seen.add(k)
        evolve_a(grid)
示例#2
0
    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)
示例#3
0
  #####.#.###.#######.#######.###.###.#.#.#  
  #.......#.......#.#.#.#.#...#...#...#.#.#  
  #####.###.#####.#.#.#.#.###.###.#.###.###  
  #.......#.....#.#...#...............#...#  
  #############.#.#.###.###################  
               A O F   N                     
               A A D   M                     """

grid = ZGrid(data, on=".", off="#")
h, w = np.array(grid).shape
dzs = [-1j, 1, 1j, -1]

# parse the warps
outside = {}
inside = {}
for z, glyph in grid.items():
    if glyph in string.ascii_uppercase:
        for dz in dzs:
            if grid.get(z + dz) == ".":
                zp = z + dz  # actual position of portal
                name = glyph + grid.get(z - dz)  # add other letter
                if 3 < z.real < w - 3 and 3 < z.imag < h - 3:
                    side = inside
                else:
                    side = outside
                if zp - z in {1j, 1}:
                    name = name[::-1]  # reverse the label
                side[name] = zp
                break

state0 = outside.pop("AA")