def critical(self, start="START"): """ 1. for each node follow the predecessors if the node has no slack. 2. traverse predecessor and repeat step 1. The function will return one critical path. If there are more critical paths it will only return one arbitrary of them. """ top = self.topological() path = Stack([self.tasks[start]]) bad = set() def _visits(task): if len(task.successors.values()) == 0: return True for t in task.successors.values(): if t.earliest_start == t.latest_start and t not in bad: path.push(t) return _visits(t) return False for t in top: if _visits(t): break pop = path.pop() bad.add(t) return path
def find_path(self, start: Vertex, end: Vertex): """return the path from start to end vertices as a graph""" vertice_stack = Stack(implementation='linked_list') edge_stack = Stack(implementation='linked_list') for i in range(self.nb_vertices): vertice_stack.push(end) if end is start: break edge = self.parent_edges[end] if edge: edge_stack.push(edge) end = edge.head else: raise Exception(f'No path found between {start} and {end}') else: raise Exception(f'No path found between {start} and {end}') vertices = [] while True: try: vertices.append(vertice_stack.pop()) except StackEmptyError: break edges = [] while True: try: edges.append(edge_stack.pop()) except StackEmptyError: break return Graph(vertices=vertices, edges=edges, directed=True)
def checkPar(s): ''' check balanced parenthesis Args: s (str): string of parenthesis ''' S = Stack() for i in s: if S.isEmpty(): if i == '(': S.push(i) # imbalance else: return False else: if S.peek() == i: S.push(i) # cancel out parenthesis else: S.pop() # only if empty (all canceled out) then balanced return S.isEmpty()
def __init__(self): # BEDMAS ==> d()!^/%*+- # PEMDAS ==> d()!^*/%+- # Precedence weighting reflects rule; higher means priority # Close bracket ')' not included; it is a special case (collapses stack to '(') self.precedence = { "(": 0, "+": 3, "-": 3, "/": 5, "*": 5, "%": 5, "C": 5, "c": 5, "^": 7, "!": 8, "d": 9 } # 's' is a stack used for rearranging infix arguments self.s = Stack() # 'q' is a queue used to store the postfix arguments self.q = Queue() self.error = False
def decoder_test(self, foreign_file, n_sentences, prune_type, alpha=None): """ Test the decoder. Input: n_sentences - The number of sentences to parse from the foreign file foreign_file - a file containing foreign sentences, one per line prune_type: "Histogram" or "Threshold" alpha: alpha for "Threshold" pruning Output: The corresponding English/Foreign sentences and its associated processing cost """ f = open(foreign_file, 'r') lines = [] [lines.append(line.split("\n")) \ for line in f.readlines()[:n_sentences]] for i in range(len(lines)): print 'Translating phrase %d of %d' % (i + 1, len(lines)) input_sent = lines[i][0].split(' ') fc_table = self.get_future_cost_table(input_sent) if alpha is None and prune_type is "Histogram": stacks = [ Stack(self.MAX_STACK_SIZE, prune_type) for x in range(len(input_sent) + 1) ] elif prune_type is "Threshold" and alpha is not None: stacks = [ Stack(self.MAX_STACK_SIZE, prune_type, alpha) for x in range(len(input_sent) + 1) ] empty_hyp = Hypothesis(None, None, input_sent, fc_table) stacks[0].add(empty_hyp) for idx, stack in enumerate(stacks): for hyp in stack.hypotheses(): for trans_opt in get_trans_opts(hyp, self.tm, self.rm, self.lm): new_hyp = Hypothesis(hyp, trans_opt) new_stack = stacks[new_hyp.input_len()] new_stack.add(new_hyp) last_stack = stacks[-1] best_hyp = last_stack.best() if best_hyp is not None: print ' '.join( [y for x in best_hyp.trans['input'] for y in x[2]]) print ' '.join(best_hyp.trans['output']) print best_hyp.trans['score']
def evaluateRPN(self): workstack = Stack() # As we pull tokens from the queue, we validate them and if neither a number # nor an operator, we abort with an error. for t in self.q.copy(): if (t in self.precedence): # As we work backwards, right value is first; validate right = workstack.pop() if (not str(right).isnumeric() and not right in self.precedence): self.error = True break # Now get left value, validate # Special case: ! only takes one argument. Make them identical if (t == "!"): left = right else: left = workstack.pop() if (not str(left).isnumeric() and not left in self.precedence): self.error = True break # Both valid, so calculate workstack.push(self.calculate(left, right, t)) else: workstack.push(int(t)) # answer is now on the stack if (not self.error): return (workstack.pop()) else: return (0)
def my_pow(base, exp, modulus): from datastructures import Stack powers = Stack() var_exp = exp while var_exp > 0: powers.push(var_exp % 2) var_exp = var_exp / 2 rem = 1 while not powers.is_empty(): p = powers.pop() rem = ((base ** p) * ((rem ** 2) % modulus)) % modulus return rem
def find_shortest_path(self, start_vetex, end_vertex): """ Return a list of vertices creating a path from the start to end vertices. Keyword arguments: start_vetex -- the starting vertex. end_vertex -- the ending vertex. Time complexity: O(V) Space complexity: O(V) """ if end_vertex.distance == float('inf'): return [] else: reverse = Stack() current_vertex = end_vertex reverse.push(current_vertex) while current_vertex != start_vetex: current_vertex = current_vertex.previous_vertex reverse.push(current_vertex) path = [] while not reverse.is_empty(): path.append(reverse.pop()) return path
def evalpostfix(postfixexpr): nums = Stack() tokenlist = list(postfixexpr.replace(' ', '')) for token in tokenlist: if token not in prec.keys(): nums.push(token) else: right = nums.pop() left = nums.pop() expression = left + token + right result = eval(expression) nums.push(str(result)) if nums.size() == 1: return nums.pop()
def ids(problem): """ Implement iterative deepening search. """ start = problem.get_start_state() depth = 1 while True: s = Stack() visited = {} d_map = {} cur = start s.push(cur) visited[start] = None d_map[start] = 1 while not s.is_empty(): cur = s.pop() if problem.is_goal_state(cur): path = [] while cur is not None: path.append(cur) cur = visited[cur] path.reverse() print len(visited) return path if d_map[cur] != depth: for state in problem.get_successors(cur): if state not in visited or d_map[cur] + 1 < d_map[state]: s.push(state) visited[state] = cur d_map[state] = d_map[cur] + 1 depth += 1
def dfs(problem): """ Implement depth-first search. """ start = problem.get_start_state() s = Stack() visited = {} cur = start s.push(start) visited[start] = None while not s.is_empty(): cur = s.pop() if problem.is_goal_state(cur): break for state in problem.get_successors(cur): if state not in visited: s.push(state) visited[state] = cur path = [] while cur is not None: path.append(cur) cur = visited[cur] path.reverse() print len(visited) return path
def checkBalance(s, d={'(': ')', '[': ']', '{': '}', '<': '>'}): ''' check balanced symbols Args: s (str): string of parenthesis d (dict): dictionary key: open symbol, value = close symbol Returns: boolean: True if balanced, False if not balanced ''' S = Stack() for i in s: # push if open symbol if i in d: S.push(i) # unbalanced if no opening to match closing or mismatch open/close symbols elif S.isEmpty() or d[S.pop()] != i: return False # no need because popped in previous statment instead of peeked # there is a match in open/close so cancel out by popping # else: #S.pop() # only if empty (all canceled out) then balanced return S.isEmpty()
def topological_sort(graph: Graph) -> List[Vertex]: """DFS: returns the list of topologically-ordered vertices in a Directed Acyclic Graph (DAG)""" if not graph.directed: raise GraphDirectionTypeError vertices = [v for v in graph.adjacency_lists] stack = Stack(implementation='linked_list') discovered_vertices = NodeList(vertices, default=False) processed_vertices = NodeList(vertices, default=False) sorted_vertices = [] def process_vertex_early(vertex: Vertex): nonlocal discovered_vertices discovered_vertices[vertex] = True def process_vertex_late(vertex: Vertex): nonlocal stack, processed_vertices processed_vertices[vertex] = True stack.push(vertex) def process_edge(head: Vertex, edgenode: Edgenode): # check that the edge is not a back edge if edgenode.edgetype is EdgeType.BACK: raise CycleInGraphError for v in vertices: if not discovered_vertices[v]: graph.dfs(start=v, process_vertex_early=process_vertex_early, process_vertex_late=process_vertex_late, process_edge=process_edge, discovered_vertices=discovered_vertices, processed_vertices=processed_vertices) while True: try: sorted_vertices.append(stack.pop()) except StackEmptyError: break return sorted_vertices
def calculate_path_volume(graph: Graph, start: Vertex, end: Vertex) -> float: stack = Stack(implementation='linked_list') parent_edges = graph.parent_edges while True: edge = parent_edges[end] if edge: stack.push(edge) end = edge.head if end is start: break else: return 0 volume = inf while True: try: volume = min(volume, stack.pop().residual) except StackEmptyError: break return volume
def checkBalance(s, d = {'(':')', '[':']', '{': '}', '<':'>'}): ''' check balanced symbols Args: s (str): string of parenthesis d (dict): dictionary key: open symbol, value = close symbol Returns: boolean: True if balanced, False if not balanced ''' S = Stack() for i in s: # push if open symbol if i in d: S.push(i) # unbalanced if no opening to match closing or mismatch open/close symbols elif S.isEmpty() or d[S.pop()] != i: return False # no need because popped in previous statment instead of peeked # there is a match in open/close so cancel out by popping # else: #S.pop() # only if empty (all canceled out) then balanced return S.isEmpty()
class SetOfStacks: LIMIT_PER_STACK = 2 def __init__(self): self.main_stack = Stack() def pop(self): if self.is_empty(): return None elif self._top_stack().is_empty(): self.main_stack.pop() self.pop() return self._top_stack().pop() def push(self, item): if self.is_empty(): self.main_stack.push(Stack()) self._top_stack().push(item) def is_empty(self): return self.main_stack.is_empty() def peek(self): if self.is_empty(): return None return self._top_stack().peek().value def _top_stack(self): return self.main_stack.peek()
class Queue2Stack(object): def __init__(self): from datastructures import Stack self.inbox = Stack() self.outbox = Stack() def push(self,item): self.inbox.push(item) def pop(self): if self.outbox.isEmpty(): while not self.inbox.isEmpty(): self.outbox.push(self.inbox.pop()) return self.outbox.pop()
def walk(room_graph: AdjSet, starting_vertex) -> List[str]: """ keep in mind the real adjacency set is [x[1] for x in vertices[v]] where x[0] is reserved as label """ walk: List[int] = list() walk_moves: List[str] = list() visited: Set[int] = set() ss: Stack = Stack() ss.push(starting_vertex) REVERSE = {'n': 's', 'e': 'w'} while ss.size > 0: vertex: int = ss.pop() if vertex not in visited: visited.add(vertex) walk.append(vertex) for neigh_dir, neigh_id in room_graph[vertex]: dead_end_: Stack = Stack() dead_end: Queue = Queue() dead_end.enqueue(neigh_id) dead_end_.push(neigh_id) walk_moves.append(neigh_dir) walk.append(neigh_id) ss.push(neigh_id) if len(room_graph[neigh_id]) == 1: while dead_end_.size > 0: walk.append(dead_end_.pop()) return walk # , walk_moves
def augment_path(graph: Graph, start: Vertex, end: Vertex, volume: float): stack = Stack(implementation='linked_list') parent_edges = graph.parent_edges while True: edge = parent_edges[end] if edge: stack.push(edge) end = edge.head if end is start: break else: break while True: try: edge = stack.pop() except StackEmptyError: break else: edge.edgenode.flow += volume edge.edgenode.residual -= volume edge.edgenode.opposite.residual += volume
def df_paths(graph: Dict[int, Dict[str, int]], starting_room: int) -> Dict[int, List[str]]: ss = Stack() visited = set() ss.push([starting_room]) paths = {(starting_room, starting_room): [starting_room]} while ss.size > 0: path: List[int] = ss.pop() room = path[-1] if room not in visited: visited.add(room) for move, nextroom in graph[room].items(): path_copy = path.copy() path_copy.append(nextroom) ss.push(path_copy) paths[(starting_room, nextroom)] = paths[(starting_room, room)] + [move] paths = {key: val[1:] for key, val in paths.items()} return paths
def revstring(mystr): ''' Reverse the characters in a string using a stack Args: mystr (string): string to reverse Returns: string: reversed string ''' s = Stack() revmystr = "" for ch in mystr: s.push(ch) while not s.isEmpty(): revmystr += s.pop() return revmystr
import sys sys.path.append('./datastructures') from datastructures import Stack if __name__ == '__main__': # tests stack = Stack() stack.push(1) assert stack.min() == 1 stack.push(2) assert stack.min() == 1 stack.push(3) assert stack.min() == 1 stack.push(0) assert stack.min() == 0 stack.pop() assert stack.min() == 1
def infix2postfix(infixexpr): opstack = Stack() postfix_list = [] tokenlist = list(infixexpr.replace(' ', '')) for token in tokenlist: if token not in prec.keys() and token != ')': postfix_list.append(token) elif token == '(': opstack.push(token) elif token == ')': top_token = opstack.pop() while top_token != '(': postfix_list.append(top_token) top_token = opstack.pop() else: while (not opstack.isEmpty() and prec[opstack.peek()] >= prec[token]): postfix_list.append(opstack.pop()) opstack.push(token) while not opstack.isEmpty(): postfix_list.append(opstack.pop()) return ''.join(postfix_list)
def quicksort(items: Sequence[KeyedItem], order=None) -> None: """O(n*log n) expected - O(n**2) worst case""" comp = lambda x, y: x > y if order == 'max' else x < y stack = Stack(implementation='linked_list') class StackItem: def __init__(self, low, high, status=0): self.low = low self.high = high self.status = status stack_item = StackItem(0, len(items) - 1) while True: low = stack_item.low high = stack_item.high if low < high: if not stack_item.status: # partition according to pivot with linear scan # pick pivot pivot_index = random.randint(low, high) pivot = items[pivot_index] items[high], items[pivot_index] = items[pivot_index], items[ high] # all items between low+1 and i are partionned against the pivot # all items below pivot index are comp(item.key, pivot.key) pivot_index = low for i in range(low, high): item = items[i] if comp(item.key, pivot.key): items[i], items[pivot_index] = items[ pivot_index], items[i] pivot_index += 1 # swap pivot to its rightful position items[high], items[pivot_index] = items[pivot_index], items[ high] # sort left of pivot stack_item.status = 1 stack.push(stack_item) stack.push(StackItem(low, pivot_index - 1)) elif stack_item.status == 1: # sort right of pivot stack_item.status = 2 stack.push(stack_item) stack.push(StackItem(pivot_index + 1, high)) try: stack_item = stack.pop() except StackEmptyError: break
def __init__(self): from datastructures import Stack self.inbox = Stack() self.outbox = Stack()
def find_strongly_connected_components(graph: Graph) -> List[List[Vertex]]: """DFS-based: returns the list of strongly-connected components""" if not graph.directed: raise GraphDirectionTypeError vertices = [v for v in graph.adjacency_lists] sscs = NodeList(vertices, default=None) # leaders are the list of the oldest vertices to be known to be # in the same SSC than each vertex leaders = NodeList(vertices, default=None) for v in leaders: leaders[v] = v discovered_vertices = NodeList(vertices, default=False) processed_vertices = NodeList(vertices, default=False) stack = Stack(implementation='linked_list') def process_vertex_early(vertex: Vertex): nonlocal stack stack.push(vertex) sscs_found = 0 def process_vertex_late(vertex: Vertex): nonlocal graph, leaders, sscs, sscs_found, stack if leaders[vertex] is vertex: sscs_found += 1 sscs[vertex] = sscs_found while True: try: v = stack.pop() except StackEmptyError: break if v is vertex: break sscs[v] = sscs_found parent_edge = graph.parent_edges[vertex] if parent_edge: parent = parent_edge.head if leaders[vertex].entry_time < leaders[parent].entry_time: leaders[parent] = leaders[vertex] def process_edge(head: Vertex, edgenode: Edgenode): nonlocal leaders, sscs tail = edgenode.tail # forward edges do not contribute to SSC # a back edge makes a SSC if edgenode.edgetype is EdgeType.BACK: # tail is in the same SSC than head # check if it is older than currrent leaders[head] if tail.entry_time < leaders[head].entry_time: leaders[head] = tail # for cross edges: # - either there is already a fully-formed SSC found # then it means it is one-way only # - or elif edgenode.edgetype is EdgeType.CROSS: if sscs[tail] is None: # SSC not assigned yet if tail.entry_time < leaders[head].entry_time: leaders[head] = tail for v in vertices: if not discovered_vertices[v]: graph.dfs(start=v, process_vertex_early=process_vertex_early, process_vertex_late=process_vertex_late, process_edge=process_edge, discovered_vertices=discovered_vertices, processed_vertices=processed_vertices) ssc_list = [[] for i in range(sscs_found)] for v in sscs: ssc_list[sscs[v] - 1].append(v) return ssc_list
def create_symbol_table(root): """ Creates a symbols table that maps each symbol to the scope within which it occurs. The symbol table has to be created in its entirety first, since entities (e.g. functions, classes) can be referenced before being defined. Similar to find_dependencies in terms of traversing the AST. TODO: refactor common stuff into separate function The data structure used is a hashtable where names are mapped to list of scopes, i.e. a hashlist. The scope can be precisely defined in terms of lineno range. The alternative is to define as scope as, e.g. <module name>.<function name> but this can lead to ambiguity since the functions etc. can be redefined. Also the lineno approach relies on the beginning lines of siblings which can lead to a larger range than actually is due to whitespaces. This gets tricky because functions can be used before they are defined, but not variables. """ set_depth(root, 0) #Initialize the stack, with the AST root stack = Stack(root) #the symbol table maps the name to the scope. #Any node can belong to multiple scopes, therefore this #is a list of scope symbol_table = STable() #this represents objects imported from #other modules other_modules = {} for node, children, ntype in stack: if ntype == "Import": #Import object has names prop which #is an array of names for name in node.names: #name can be the name or an alias name_val = name.asname or name.name #insert in symbol_table symbol_table[name_val] = () elif ntype == "ImportFrom": if node.names[0].name == '*': try: imp_mod = importlib.import_module(node.module) #Add all names in imported module, except those #starting with '_' for name in dir(imp_mod): if name[0] != '_': symbol_table[name] = stack_top(scopes) except ImportError: print "Error: local system does not have {}. Skipping!".format(node.module) pass else: #TODO: store node.module for name in node.names: #TODO: store name.name even if name.asname defined name_val = name.asname or name.name symbol_table[name_val] = stack.get_scopes(src_module=node.module) elif ntype == "ClassDef" or ntype == "FunctionDef": symbol_table[node.name] = stack.get_scopes() #NOTE: if a name is being loaded then it already exists and doesn't need #to be added to symbol_table elif ntype == "Name" and not is_load(children) and not has_global(stack.scope_tail(), node.id): symbol_table[node.id] = stack.get_scopes() elif ntype == "arguments": if node.vararg: symbol_table[node.vararg] = stack.get_scopes() if node.kwarg: symbol_table[node.kwarg] = stack.get_scopes() elif ntype == "Global": #add a list global vars on node on the top of #the stack #nonlocal could be handled in similar way set_globals(scopes[-1], node.names) #set lineno property of children nodes set_lineno(node, children) for child in children[::-1]: #set depth of child set_depth(child, node.depth + 1) #Add children to stack stack.append(child) #Add any new scopes #Need to do it here since scoping_nodes are defined in their parent scope stack.check_and_push_scope() print "Symbol table is " print symbol_table return symbol_table
def find_dependencies(root): """ Finds all dependencies in root object based on symbol table. Consider a dependecy as containing a source and a destination. Cases (nodes) to account for: 1) Assign -check for the Name being assigned 2) Name being invoked -here it makes sense to search for name 3) Attribute e.g. pdb.set_trace(), set_trace is an attribute of pdb -see check dependency 4) Import These are needed when building a symbols table 5) ImportFrom ibid Gotchas: 1) a name being stored i.e. a name collisions that makes it seem like a dependency exists 2) x = y = z = 3 3) Attribute chains can be arbitrarily long x.y.z, or x().y().z(), or some combination thereof There are a lot of cases to be handled Arguments: root:- the root of the AST being analyzed stored as (2-tuple) with (root node, array of children ) """ symbol_table = create_symbol_table(root) names = [] #Set the depth of the root node set_depth(root, 0) #Stack of nodes to visit stack = Stack(root) #List of (src, dest) of dependencies dependency_table = DTable(symbol_table=symbol_table) for node, children, ntype in stack: stack.check_and_push_scope() #A Name is being loaded, therefore if ntype == "Name" and is_load(children): """ """ dependency_table.append( (stack.scopes, node)) elif ntype == "Assign": #TODO need to add assignments and then revoke them #for child in children: #print children pass elif ntype == "Attribute": #TODO: attribute chains can be arbitrarily long #dep_dest = "{}.{}".format(node.value.id, node.attr) #print "{} => {}".format(scopes_to_str(scopes), dep_dest) #TODO: Can't just do dependency_table.append( (scopes, node)) #since the unique_id function won't match the create the dep string like #{node.value.id}.{node.attr}. #Either generalize unique_id or something else. #Don't add children continue set_lineno(node, children) #Add children to stack #This musn't always be performed for child in children[::-1]: set_depth(child, node.depth + 1) stack.append(child) print "dependency table is " print dependency_table
def test_primitives(): stack = Stack() with pytest.raises(NotImplementedError): stack.push('a') with pytest.raises(NotImplementedError): stack.pop()
# nsew = list(neighbs.keys()) # random_dir = random.choice(nsew) # random_neighb = neighbs[random_dir] # #print(random_dir, random_neighb) # if random_neighb != '?': # build_up[room][random_dir] = random_neighb # traversal.append(random_dir) # room, neighbs = rooms_neighbs.pop(0) #print(build_up) #print(traversal) visited_rooms = set() player.currentRoom = world.startingRoom visited_rooms.add(player.currentRoom) traversalPath = list() ss = Stack() qq = Queue() while len(visited_rooms) != len(roomGraph.keys()): move = random.choice(player.currentRoom.getExits()) if room_graph[player.currentRoom.id][move] not in visited_rooms: ss.push(move) while ss.size > 0: dir_move: str = ss.pop() if dir_move in room_graph[player.currentRoom.id].keys(): if room_graph[player.currentRoom.id][dir_move] not in visited_rooms: print(dir_move) player.travel(dir_move)
def mergesort(items: Sequence[KeyedItem], order=None) -> None: """O(n*log n)""" comp = lambda x, y: x > y if order == 'max' else x < y stack = Stack(implementation='linked_list') class StackItem: def __init__(self, low, high, status=0): self.low = low self.high = high self.status = status stack_item = StackItem(0, len(items) - 1) while True: low = stack_item.low high = stack_item.high if low != high: median = (low + high) // 2 if not stack_item.status: # sort left stack_item.status = 1 stack.push(stack_item) stack.push(StackItem(low, median)) elif stack_item.status == 1: # sort right stack_item.status = 2 stack.push(stack_item) stack.push(StackItem(median + 1, high)) else: # merge left_queue = Queue(implementation='doubly_linked_list') for i in range(low, median+1): left_queue.enqueue(items[i]) right_queue = Queue(implementation='doubly_linked_list') for i in range(median+1, high+1): right_queue.enqueue(items[i]) for i in range(low, high + 1): if not left_queue.head: items[i] = right_queue.dequeue() elif not right_queue.head: items[i] = left_queue.dequeue() else: if comp(left_queue.head.key, right_queue.head.key): items[i] = left_queue.dequeue() else: items[i] = right_queue.dequeue() try: stack_item = stack.pop() except StackEmptyError: break
def test_array_implementation_empty_stack(): stack = Stack(implementation='array') with pytest.raises(StackEmptyError): stack.pop()
def push(self, item): if self.is_empty(): self.main_stack.push(Stack()) self._top_stack().push(item)
def test_linked_list_implementation(): stack = Stack(implementation='linked_list') a, b, c, d = list('abcd') stack.push(a) assert stack.pop() is a stack.push(b) stack.push(c) assert stack.pop() is c stack.push(d) assert stack.pop() is d assert stack.pop() is b
def __init__(self): self.main_stack = Stack()
def test_linked_list_implementation_empty_stack(): stack = Stack(implementation='linked_list') with pytest.raises(StackEmptyError): stack.pop()