def dq_evaluate_prefix(prefix_expr): """ 1. add numbesr to stack 2. whne you reach an operator pop the stack twice 3 perform the math of the opeartor """ print(prefix_expr) op_stack = Stack() numeral_tokens = \ "0123456789" operator_tokens = \ "+-*/" import operator operator_to_fn_map = \ { "+" : operator.add, "*" : operator.mul, "-" : operator.sub, "/" : operator.__truediv__, } #start parsing for token in prefix_expr[::-1]: print("Stack -> %s" %(op_stack.items)) #case operand if token in numeral_tokens: op_stack.push(token) #case operator elif token in operator_tokens: second_operand = \ op_stack.pop() first_operand = \ op_stack.pop() #perform math operator_fn = \ operator_to_fn_map[token] result = \ operator_fn( int(first_operand), int(second_operand) ) #push result to stack op_stack.push(result) return op_stack.pop()
class MaxStack: def __init__(self) -> None: self.stack = Stack() self.maximum = Stack() def __repr__(self) -> str: return f"Stack: {self.stack}\nMax Stack: {self.maximum}" def push(self, val: int) -> None: self.stack.push(val) # if the current value is larger than the previous maxima, its index is added # to the maximum stack if self.maximum.is_empty() or self.stack[self.maximum.peek()] < val: self.maximum.push(len(self.stack) - 1) def pop(self) -> int: if self.stack.is_empty(): raise RuntimeError("Cannot pop from a empty stack") # if the index of the current element to be removed is in the maximum stack, # its removed as well if len(self.stack) == self.maximum.peek() + 1: self.maximum.pop() return self.stack.pop() def max(self) -> int: if self.stack.is_empty(): raise RuntimeError("Cannot get max of a empty stack") # the maximum is accessed from the last poistion stored in maximum stack return self.stack[self.maximum.peek()]
class Queue: def __init__(self) -> None: self.stack1 = Stack() self.stack2 = Stack() def __str__(self) -> str: return str(self.stack2[::-1] + self.stack1[::]) def enqueue(self, val: int) -> None: self._transfer_to_stack1() self.stack1.push(val) def dequeue(self) -> int: self._transfer_to_stack2() if len(self.stack2) == 0: raise RuntimeError("Cannot dequeue from a empty queue") return self.stack2.pop() def _transfer_to_stack2(self) -> None: # helper function to transfer all items to the stack 1 from stack 2 while not self.stack1.is_empty(): self.stack2.push(self.stack1.pop()) def _transfer_to_stack1(self) -> None: # helper function to transfer all items to the stack 2 from stack 1 while not self.stack2.is_empty(): self.stack1.push(self.stack1.pop())
def build_expression_tree(expression): exp_list = expression.split() stack = Stack() tree = BinaryTree('') stack.push(tree) current_tree = tree for item in exp_list: if item == '(': current_tree.insert_left('') stack.push(current_tree) current_tree = current_tree.get_left() elif item not in ['+', '-', '/', '*', ')']: current_tree.set_root(item) parent = stack.pop() current_tree = parent elif item in ['+', '-', '/', '*']: current_tree.set_root(item) current_tree.insert_right('') stack.push(current_tree) current_tree = current_tree.get_right() elif item == ')': current_tree = stack.pop() else: raise ValueError return tree
def get_min_changes_helper(string: str, modifications: int, stack: Stack, current: str) -> Tuple[int, str]: if not string and stack.is_empty(): return modifications, current elif not string: additions = len(stack) return modifications + additions, current + (")" * additions) if string[0] == "(": stack_added = deepcopy(stack) stack_added.push("(") modifications1, string1 = get_min_changes_helper( string[1:], modifications, stack_added, current + "(") # adding to stack modifications2, string2 = get_min_changes_helper( string[1:], modifications + 1, stack, current) # removing from string return min( [(modifications1, string1), (modifications2, string2)], key=lambda tup: tup[0], ) if not stack.is_empty(): stack.pop() return get_min_changes_helper(string[1:], modifications, stack, current + ")") return get_min_changes_helper(string[1:], modifications + 1, stack, current)
class Queue: def __init__(self): self.add_stack = Stack() self.rem_stack = Stack() def push(self, val): self.add_stack.push(val) def pop(self): if len(self.rem_stack) > 0: return self.rem_stack.pop() if len(self.add_stack) < 1: return None for i in range(len(self.add_stack) - 1): self.rem_stack.push(self.add_stack.pop()) return self.add_stack.pop() def is_empty(self): return (len(self.add_stack) + len(self.rem_stack)) == 0 def __iter__(self): if len(self.rem_stack) > 0: node = self.rem_stack.head while node is not None: yield node node = node.next if len(self.add_stack) > 0: for node in self.add_stack.rev_iter(): yield node
def convert_infix_to_postfix(infix_expression): operator_dictionary = {"+":2, "-":2, "/":3, "*":3, "(":1} operator_stack = Stack() postfix_list = [] index = 0 while index < len(infix_expression): token = infix_expression[index]; if token in "ABCDEFGHIJKLMNOPQRSTUVWXYZ" or \ token in "0123456789": postfix_list.append(token) elif token == '(': operator_stack.push('(') elif token == ")": top_token = operator_stack.pop() while top_token != "(": postfix_list.append(top_token) top_token = operator_stack.pop() else: while not operator_stack.is_empty() and \ operator_dictionary[operator_stack.peek()] >= operator_dictionary[token]: postfix_list.append(operator_stack.pop()) operator_stack.push(token) index += 1 #return postfix expression while not operator_stack.is_empty(): postfix_list.append(operator_stack.pop()) return "".join(postfix_list)
def testingLoopingScenario(): m = Stack() m.push("x") m.push("y") m.push("z") while not m.is_empty(): m.pop() m.pop()
def eliminated_pieces_last_move(self, curr_phase, curr_move_count, pop=True): eliminated_pieces = { constant.WHITE_PIECE: [], constant.BLACK_PIECE: [] } eliminated_pieces_tup = { constant.WHITE_PIECE: [], constant.BLACK_PIECE: [] } # generally speaking last_phase = curr_phase last_move_count = curr_move_count - 1 # check the boundary of the phase transition if curr_move_count == 0 and curr_phase == constant.MOVING_PHASE: last_phase = constant.PLACEMENT_PHASE last_move_count = 23 # peak into the eliminated piece stack for colour in (constant.WHITE_PIECE, constant.BLACK_PIECE): piece_tup = Stack.peek(self.eliminated_pieces[colour]) # print(piece_tup) # check if the stack is populated, else we continue with the next piece if piece_tup is None: continue # else we can get the phase and move_counter for that eliminated piece phase = piece_tup[1] move_count = piece_tup[2] # while loop to get all pieces that were eliminated in the last move while phase == last_phase and move_count == last_move_count: Stack.pop(self.eliminated_pieces[colour]) eliminated_pieces[colour].append(piece_tup[0]) eliminated_pieces_tup[colour].append(piece_tup) piece_tup = Stack.peek(self.eliminated_pieces[colour]) if piece_tup is None: break phase = piece_tup[1] move_count = piece_tup[2] if pop is False: for colour in (constant.WHITE_PIECE, constant.BLACK_PIECE): # push each piece back to the respective queues for piece_tup in eliminated_pieces_tup[colour]: Stack.push(self.eliminated_pieces[colour], piece_tup) return eliminated_pieces
def test0(self): stack = Stack() stack.push(1) self.assertEqual(stack.size(), 1) stack.push(2) stack.push(2) stack.push(2) stack.push(2) self.assertEqual(stack.size(), 5) stack.pop() self.assertEqual(stack.size(), 4)
def testingOperations(): print("testingOperations") m = Stack() m.push('x') m.push('y') m.debug_print() m.pop() m.debug_print() m.push('z') m.debug_print() print(m.peek())
def postfix_eval(postfix_expr): operand_stack = Stack() token_list = postfix_expr.split() for token in token_list: if token in "0123456789": operand_stack.push(int(token)) else: operand2 = operand_stack.pop() operand1 = operand_stack.pop() result = do_math(token, operand1, operand2) operand_stack.push(result) return operand_stack.pop()
def get_shortest_standardized_path(path: str) -> str: path_list = path.split("/") stack = Stack() for curr_directory in path_list: if curr_directory == ".": continue elif curr_directory == "..": stack.pop() else: stack.push(curr_directory) return "/".join(stack)
def get_view_sunset(arr: List[int]) -> int: # the buildings can view the sunset when the elements are chosen in-order, keeping # only the ones that allow decending order selection stack = Stack() for elem in arr: if not stack.is_empty(): last = stack.peek() while not stack.is_empty() and last < elem: stack.pop() last = maxsize if not stack.is_empty(): last = stack.peek() if stack.is_empty() or stack.peek() > elem: stack.push(elem) return len(stack)
def get_transformation(arrangement: List[str]) -> List[str]: stack = Stack() for qux in arrangement: if stack.is_empty() or stack.peek() == qux: stack.push(qux) else: qux_last = stack.pop() while True: # backpropagating in case the previous quxes needs to be updated qux = generate_new_qux(qux_last, qux) if stack.is_empty() or stack.peek() == qux: break qux_last = stack.pop() stack.push(qux) return stack
class queueWith2Stacks: def __init__(self): self.stack1 = Stack() self.stack2 = Stack() def enqueue(self, value): self.stack1.push(value) def dequeue(self): if not self.stack2.size() > 0: self.move_content() return self.stack1.pop() def move_content(self): while self.stack1.size() > 0: self.stack2.push(self.stack1.pop())
def par_checker(symbol_string): def matches(open, close): opens = "([{" closes = ")]}" return opens.index(open) == closes.index(close) s = Stack() balanced = True index = 0 while index < len(symbol_string) and balanced: symbol = symbol_string[index] if symbol in "([{": s.push(symbol) else: if s.is_empty(): balanced = False else: top = s.pop() if not matches(top, symbol): balanced = False index = index + 1 if balanced and s.is_empty(): return True else: return False
def DFS(graph, s): ''' Depth-first search implementation: DFS is an algorithm for traversing or searching tree or graph data structures. It starts at the tree root and explores as far as possible along each branch before backtracking. :param graph: the graph to be searched, nodes have to be integers :param s: the source node, where the search begins :return: ordered list of nodes of DFS traversal ''' if graph.count_nodes() == 0: return [] dfs = [] visited = [] stack = Stack() stack.push(s) visited.append(s) while len(stack) > 0: current = stack.pop() dfs.append(current) for n in graph[current]: if n not in visited: stack.push(n) visited.append(n) return dfs
def generate_tree_helper(i: int, arr: List[BinaryTree], nodes: int) -> BinaryTree: tree = arr[i] stack = Stack() stack.push(tree.root) while not stack.is_empty(): # generating the new tree with 1 new node node = stack.pop() if not node.left: node.left = Node(0) for j in range(nodes): if j != i and tree == arr[j]: node.left = None break else: return tree else: stack.push(node.left) if not node.right: node.right = Node(0) for j in range(nodes): if j != i and tree == arr[j]: node.right = None break else: return tree else: stack.push(node.right)
def evaluate_postfix_expression(postfix_expression): expression_stack = Stack() index = 0 while index < len(postfix_expression): token = postfix_expression[index] if token in "0123456789": expression_stack.push(int(token)) else: second = expression_stack.pop() first = expression_stack.pop() result = StackAlgorithms.evaluate_expression(first, second, token) expression_stack.push(result) index += 1 return expression_stack.pop()
def is_balanced(ip): s = Stack() match_pair = {')': '(', ']': '[', '}': '{'} for item in ip: if item == '{' or item == '(' or item == '[': s.push(item) else: if match_pair[item] == s.peak(): s.pop() else: return False ''' Return True if stack is empty, False otherwise ''' return not s.size()
def can_balance_parentheses(string: str, stack: Stack = Stack()) -> bool: if not string and stack.is_empty(): return True elif not string: return False # checking if the parentheses can be balanced if string[0] == "(": stack.push("(") return can_balance_parentheses(string[1:], stack) elif string[0] == ")": if not stack.is_empty() and stack.peek() == "(": stack.pop() return can_balance_parentheses(string[1:], stack) return False elif string[0] == "*": return (can_balance_parentheses("(" + string[1:], deepcopy(stack)) or can_balance_parentheses(")" + string[1:], deepcopy(stack)) or can_balance_parentheses(string[1:], deepcopy(stack)))
def interleave(stack: Stack) -> Stack: queue = Queue() # interleaving the elements for i in range(1, len(stack)): for _ in range(i, len(stack)): queue.enqueue(stack.pop()) for _ in range(len(queue)): stack.push(queue.dequeue()) return stack
def is_parenthesis_balanced( string: str, parenthesis_map: Dict[str, str] = { "{": "}", "[": "]", "(": ")" }) -> bool: open_parenthesis_set = set(parenthesis_map.keys()) stack = Stack() # iterating through the string and checking if its balanced for char in string: if char in open_parenthesis_set: stack.push(char) elif not stack.is_empty() and parenthesis_map[stack.peek()] == char: stack.pop() else: return False # the string is balanced only if the stack is empty (equal number of opening and # closing parenthesis) return stack.is_empty()
def calculate(expression_list: List[Union[int, str]]) -> Union[float, int]: stack = Stack() # calculating the expression for expression in expression_list: if expression in FUNCTIONS: a = stack.pop() b = stack.pop() stack.push(FUNCTIONS[expression](a, b)) else: stack.push(expression) return stack[0]
def testingMyApproach(): open_brace = '(' close_brace = ")" stack = Stack() string_to_test = "((()))" for index in range(0, len(string_to_test)): char = string_to_test[index] if char == open_brace: stack.push(char) print("push") print(stack.items) if char == close_brace: stack.pop() print("pop") print(stack.items) print(stack.is_empty())
def par_checker(symbol_string): s = Stack() balanced = True index = 0 while index < len(symbol_string) and balanced: symbol = symbol_string[index] if symbol == "(": s.push(symbol) else: if s.is_empty(): balanced = False else: s.pop() index = index + 1 if balanced and s.is_empty(): return True else: return False
class Quack: def __init__(self) -> None: self.stack_1 = Stack() self.stack_2 = Stack() self.stack_3 = Stack() self.elements = 0 def __len__(self) -> int: return self.elements def push(self, x: int) -> None: self.stack_1.push(x) self.stack_2.push(x) self.elements += 1 def pop(self) -> int: if self.elements == 0: raise RuntimeWarning("Quack underflow") if len(self.stack_2) == 0: while not self.stack_3.is_empty(): self.stack_2.push(self.stack_3.pop()) self.elements -= 1 self.stack_2.pop() return self.stack_1.pop() def pull(self) -> int: if self.elements == 0: raise RuntimeWarning("Quack underflow") if len(self.stack_3) == 0: while not self.stack_2.is_empty(): self.stack_3.push(self.stack_2.pop()) self.elements -= 1 return self.stack_3.pop()
def evaluating_a_prefix(postfix_expr): numeral_tokens = \ "0123456789" operator_tokens = \ "+-*/" import operator operator_to_fn_map = \ { "+" : operator.add, "*" : operator.mul, "-" : operator.sub, "/" : operator.__truediv__, } op_stack = Stack() for token in postfix_expr: if token in numeral_tokens: op_stack.push(token) if token in operator_tokens: second_operand = \ op_stack.pop() first_operand = \ op_stack.pop() result = \ operator_to_fn_map[token]( int(first_operand), int(second_operand)) op_stack.push(result) return op_stack.pop()
def convert_to_base(dividend, base): s = Stack() hexadecimal = "0123456789ABCDEF" while dividend > 0: s.push(dividend % base) dividend //= base; length = s.size() binary = "" while length > 0: binary += str(hexadecimal[s.pop()]) length -= 1 return binary
class MinStack: def __init__(self): self.normal = Stack() self.mins = Stack() def isEmpty(self): return self.normal.top == None def peek(self): if self.isEmpty(): "print empty... cant peek" return None num = self.mins.pop().data self.mins.push(num) return num def push(self, num): if self.isEmpty(): self.normal.push(num) self.mins.push(num) return if self.peek() >= num: self.mins.push(num) self.normal.push(num) def pop(self): value = self.normal.pop() if value == self.peek(): self.mins.pop() return value def get_min(self): return self.peek()
def max_area_histogram(histogram: List[int]): stack = Stack() max_area = 0 index = 0 while index < len(histogram): if stack.is_empty() or histogram[stack.peek()] <= histogram[index]: stack.push(index) index += 1 else: # if the current bar is lower than top of stack, the area of rectangle # needs to be calculated with the stack top as the smallest (or minimum # height) bar. top_of_stack = stack.pop() area = histogram[top_of_stack] * ( (index - stack.peek() - 1) if not stack.is_empty() else index) max_area = max(max_area, area) # calculating the area formed by the indices still in the stack while not stack.is_empty(): top_of_stack = stack.pop() area = histogram[top_of_stack] * ( (index - stack.peek() - 1) if not stack.is_empty() else index) max_area = max(max_area, area) return max_area
def testingMyApproach(string_to_test): open_braces = '({[' stack = Stack() for index in range(0, len(string_to_test)): char = string_to_test[index] if char in open_braces: stack.push(char) else: top = stack.pop() if not BalancingALotOfSymbols.matches(top, char): stack.push(top) print(stack.is_empty())
def check_path_exists_BFS(G, u, v): stack = Stack() stack.push(u) G.nodes[u]['weight'] = 1 while not stack.isEmpty(): current = stack.pop() for n in G.neighbors(current.data): if n == v: return True if G.nodes[n]['weight'] == 0: stack.push(n) G.nodes[n]['weight'] = 1 return False
def is_paranthesis_balanced(symbol_string): s = Stack() index = 0 balanced = True length = len(symbol_string) while index < length and balanced: symbol = symbol_string[index] if symbol in "({[": s.push(symbol) else: if s.is_empty(): balanced = False else: start = s.pop() if not StackAlgorithms.matches(start, symbol): balanced = False index += 1 if s.is_empty() and balanced: return True else: return False