Example #1
0
def part2(_, state):
    """Solve for the answer to part 2."""
    distances = state["distances"]
    start_portal = state["start_portal"]
    end_portal = state["end_portal"]

    Node = collections.namedtuple("Node", "portal level")

    def get_edges(node):
        # Walking edges
        for portal, dist in distances[node.portal].items():
            yield Node(portal, node.level), dist
        # Teleporting edges
        if node.portal.label not in ("AA", "ZZ"):
            if node.portal.is_inner:
                yield Node(flip_portal(node.portal), node.level + 1), 1
            elif node.level > 0:
                yield Node(flip_portal(node.portal), node.level - 1), 1

    # Assume the shortest path doesn't go beyond level 50
    max_level = 50
    return dijkstra(
        nodes={
            Node(portal, level)
            for portal in distances.keys() for level in range(max_level + 1)
        },
        edge_producer=get_edges,
        start_node=Node(start_portal, level=0),
        end_node=Node(end_portal, level=0),
    )
Example #2
0
 def node_distance_matrix(self):
     self.alldistances = {}
     nnodes = len(self.node_list)
     self.distancematrix = np.empty((nnodes, nnodes))
     for node in self.node_list:
         distance, pred = util.dijkstra(self, self.edge_lengths, node, n=float('inf'))
         pred = np.array(pred)
         tree = util.generatetree(pred)
         self.alldistances[node] = (distance, tree)
         self.distancematrix[node] = distance
Example #3
0
 def node_distance_matrix(self, n_processes):
     """
     Called from: allneighbordistances()
                  nearestneighbordistances()
                  distancebandweights()
     """
     self.alldistances = {}
     nnodes = len(self.node_list)
     self.distancematrix = np.empty((nnodes, nnodes))
     # Single-core processing
     if not n_processes:
         for node in self.node_list:
             distance, pred = util.dijkstra(self,
                                            self.edge_lengths,
                                            node,
                                            n=float('inf'))
             pred = np.array(pred)
             #tree = util.generatetree(pred)     <---- something to look at in the future
             tree = None
             self.alldistances[node] = (distance, tree)
             self.distancematrix[node] = distance
     # Multiprocessing
     if n_processes:
         import multiprocessing as mp
         from itertools import repeat
         if n_processes == "all":
             cores = mp.cpu_count()
         else:
             cores = n_processes
         p = mp.Pool(processes=cores)
         distance_pred = p.map(
             util.dijkstra_multi,
             zip(repeat(self), repeat(self.edge_time), self.node_list))
         distance = [
             distance_pred[iteration][0]
             for iteration in range(len(distance_pred))
         ]
         pred = [
             distance_pred[iteration][1]
             for iteration in range(len(distance_pred))
         ]
         pred = np.array(pred)
         #tree = util.generatetree(pred[node])
         for node in self.node_list:
             self.distancematrix[node] = distance[node]
Example #4
0
def part1(maze, state):
    """Solve for the answer to part 1."""
    inner_portals, outer_portals = find_portals(maze)
    distances = state["distances"] = find_distances(maze, inner_portals,
                                                    outer_portals)
    start_portal = state["start_portal"] = Portal(label="AA", is_inner=False)
    end_portal = state["end_portal"] = Portal(label="ZZ", is_inner=False)

    def get_edges(portal):
        # Walking edges
        yield from distances[portal].items()
        # Teleporting edges
        if portal.label not in ("AA", "ZZ"):
            yield flip_portal(portal), 1

    return dijkstra(
        nodes=distances.keys(),
        edge_producer=get_edges,
        start_node=start_portal,
        end_node=end_portal,
    )
Example #5
0
 def node_distance_matrix(self, n_processes):
     """
     Called from: allneighbordistances()
                  nearestneighbordistances()
                  distancebandweights()
     """
     self.alldistances = {}
     nnodes = len(self.node_list)
     self.distancematrix = np.empty((nnodes, nnodes))
     # Single-core processing
     if not n_processes:
         for node in self.node_list:
             distance, pred = util.dijkstra(self, self.edge_lengths, node, n=float('inf'))
             pred = np.array(pred)
             #tree = util.generatetree(pred)     <---- something to look at in the future
             tree = None
             self.alldistances[node] = (distance, tree)
             self.distancematrix[node] = distance
     # Multiprocessing
     if n_processes:
         import multiprocessing as mp
         from itertools import repeat
         if n_processes == "all":
             cores = mp.cpu_count()
         else:
             cores = n_processes
         p = mp.Pool(processes=cores)
         distance_pred = p.map(util.dijkstra_multi, zip(repeat(self), 
                                                    repeat(self.edge_time), 
                                                    self.node_list))
         distance = [distance_pred[iteration][0] for iteration in range(len(distance_pred))]
         pred = [distance_pred[iteration][1] for iteration in range(len(distance_pred))]
         pred = np.array(pred)
         #tree = util.generatetree(pred[node])
         for node in self.node_list:
             self.distancematrix[node] = distance[node]