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), )
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
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]
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, )
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]