def depthFirstSearch(graph: com.Graph, currentNode: str, endNode: str, visited: Set[str], currentPath: List[str], allPaths: list): if currentNode in visited: return if not isBigCave(currentNode): visited.add(currentNode) currentPath.append(currentNode) if currentNode == endNode: allPaths.append(currentPath) return edges = graph.direct_connected_weights_and_edges(currentNode) for node in edges: if node not in visited: depthFirstSearch(graph, node, endNode, set(visited), list(currentPath), allPaths)
def depthFirstSearchAllowRevisited(graph: com.Graph, currentNode: str, endNode: str, visited: Set[str], visitedTwice: Set[str], currentPath: List[str], allPaths: list): if not canVisit(currentNode, visited, visitedTwice, True): return currentPath.append(currentNode) if currentNode == endNode: allPaths.append(currentPath) return edges = graph.direct_connected_weights_and_edges(currentNode) for node in edges: if canVisit(node, visited, visitedTwice): depthFirstSearchAllowRevisited(graph, node, endNode, set(visited), set(visitedTwice), list(currentPath), allPaths)
def findShortest(graph: com.Graph, currentNode, ownedKeys: set, allKeys: set, currentSteps: int): pathQueue = deque() alreadyHit = {} alreadyHit[(currentNode, frozenset(ownedKeys))] = currentSteps keysInOrder = list() pathQueue.append((currentSteps,currentNode, ownedKeys, keysInOrder)) allKeysHash = frozenset(allKeys).__hash__() shortestSoFar = impossible shortestPath = None while pathQueue: currentSteps, currentNode, ownedKeys, keysInOrder = pathQueue.popleft() ownedKeys = ownedKeys.copy() keysInOrder = keysInOrder.copy() if isKey(currentNode): ownedKeys.add(currentNode) keysInOrder.extend(currentNode) currentOwnedKeys = frozenset(ownedKeys) if allKeysHash == currentOwnedKeys.__hash__(): if shortestSoFar >= currentSteps: shortestSoFar = currentSteps shortestPath = keysInOrder continue else: continue for weight, edge in graph.direct_connected_weights_and_edges(currentNode): newSteps = currentSteps + weight if isDoor(edge) and edge.lower() not in ownedKeys: continue if alreadyHit.get((edge, currentOwnedKeys)): if alreadyHit.get((edge, currentOwnedKeys)) < newSteps: continue alreadyHit[(edge, currentOwnedKeys)] = newSteps pathQueue.append((newSteps, edge, ownedKeys, keysInOrder)) return shortestSoFar, shortestPath