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) -> 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())
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 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
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()]
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 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
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 testingLoopingScenario(): m = Stack() m.push("x") m.push("y") m.push("z") while not m.is_empty(): m.pop() m.pop()
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 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 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
def parantheses_checker_rewrite(symbol_string): isBalanced = True stack = Stack() open_chars = "({[" def is_a_match(open_char, close_char): open_chars = "({[" close_chars = ")}]" if open_chars.index(open_char) == close_chars.index(close_char): return True else: return False #enumerate the string for char in symbol_string: if char in open_chars: stack.push(char) else: #check if stack is is_empty if stack.is_empty(): isBalanced = False else: poppedVal = stack.pop() if is_a_match(poppedVal, char): #match pass else: isBalanced = False print(isBalanced) print(stack.items) if isBalanced and stack.is_empty(): return True else: 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
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 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 sort_stack(stack): """ I think this is bubble sort Space: O(1) Time: O(n^2?) :param s1: Stack Class :return: Stack Class sorted """ def swap(stack1, stack2): """swaps the first elements of two stacks""" temp = stack1.pop() stack1.push(stack2.pop()) stack2.push(temp) buffer = Stack() not_sorted = True count = 0 while not_sorted: while not stack.is_empty(): s1, s2 = stack.peek(), buffer.peek() if s2 is not None and s1 < s2: swap(buffer, stack) buffer.push(stack.pop()) not_sorted = False last = None while not buffer.is_empty(): a = buffer.pop() stack.push(a) if last is not None and last < a: not_sorted = True last = a count += 1 return stack
def dq_divide_by_base(base , element): """ Summary ------------- Convert the give number (element) to a number in the specified Base (base) if none specified, Binary is assumed Logic ----- Perform divide_by_2 algorithm extended to use for all bases store reminders in a Stack enumerate the Stack use each element in the stack as an index to a digit set corresponding to each base convert all elemnts in te stack to the corresponding elements in the digit set Parameters ---------- arg1 : base base. Member of "Base" enum class specifies what base needs to be used BINARY.HEX.OCT are supported arg2 : element element. Memeber of "int" class number to be converted Returns ------- str number in desired base """ binary_digit_set = [0,1,2,3,4,5,6,7,8,9] hex_digit_set = [0,1,2,3,4,5,6,7,8,9,"A","B","C","D","E","F"] oct_digit_set = [0,1,2,3,4,5,6,7] divisor = 0 #find the appropriate divisor to perform divide_by_base algorithm if base == Base.BINARY: divisor = Base.BINARY.value if base == Base.HEX: divisor = Base.HEX.value if base == Base.OCTA: divisor = Base.OCTA.value reminder_stack = Stack() reminder = 0 quotient = element #divide_by_base algorithm while quotient > 0: reminder = quotient % divisor quotient = quotient // divisor #push reminder to stack reminder_stack.push(reminder) print(reminder_stack.items) number_string = "" #convert number to string #substitude characters from digit_sets while not reminder_stack.is_empty(): digit = "" final_reminder = reminder_stack.pop() if base == Base.BINARY: digit = str(binary_digit_set[final_reminder]) if base == Base.HEX: digit = hex_digit_set[final_reminder] if digit is str: digit = str(digit) if base == Base.OCTA: digit = str(oct_digit_set[final_reminder]) number_string = number_string + digit return number_string
def dq_infix_to_prefix_two_stacks_method(infix_expr): #precedence table prec = {} prec["*"] = 3 prec["/"] = 3 prec["+"] = 2 prec["-"] = 2 prec[")"] = 1 alaphabet_tokens = \ "ABCDEFGHIJKLMNOPQRSTUVWXYZ" numeral_tokens = \ "0123456789" #stack to hold operators op_stack = Stack() #list to hold operands #and final result prefix_stack = Stack() #split the expression tokens_list = \ infix_expr.split() #print("tokens_list %s" %(tokens_list)) # evaluate the expression # we start evaluating left to right # 1. reverse the list tokens_list_reversed = \ tokens_list[::-1] #expression enumration begin for token in tokens_list_reversed: #2. case ")" # since we start from the end of the expression # we consider "(" to be end of the grouping if token is ")": op_stack.push(token) #3.case operand elif token in alaphabet_tokens or \ token in numeral_tokens: prefix_stack.push(token) #4. case "(" elif token is "(": # marks the end of expression or # closing of a grouping () # move all operators till "(" to output top_operator = \ op_stack.pop() while not top_operator is ")": prefix_stack.push(top_operator) top_operator = \ op_stack.pop() else: #ie. for +,*,-./ # compare with all ops in the op_stack # find out if there is any operator with higher precedence # if yes add all of them to output # push to op_stack while not op_stack.is_empty() and \ prec[op_stack.peek()] >= prec[token]: #move them to output operator = \ op_stack.pop() prefix_stack.push(operator) #if op_stack is empty #push the operator to op_stack op_stack.push(token) #expression enumration complete #move the remaining items while not op_stack.is_empty(): operator = \ op_stack.pop() prefix_stack.push(operator) #join the string joined_string = "" while not prefix_stack.is_empty(): string = prefix_stack.pop() joined_string+= " " + string #return " ".join(prefix_stack.items[::-1]) return joined_string
def infix_to_postfix(infix_expr): #precedence table prec = {} prec["*"] = 3 prec["/"] = 3 prec["+"] = 2 prec["-"] = 2 prec["("] = 1 alaphabet_tokens = \ "ABCDEFGHIJKLMNOPQRSTUVWXYZ" numeral_tokens = \ "0123456789" #stack to hold operators op_stack = Stack() #list to hold operands #and final result postfix_list = [] #split the expression tokens_list = \ infix_expr.split() #evaluate the expression """ #1 match alphabet or numeral tokes and add them to """ #enumerate the expression for token in tokens_list: #look for a matching alphabet or numeral token if token in alaphabet_tokens or \ token in numeral_tokens : #if matches add it to postfix_list postfix_list.append(token) #look for matching "(" #push it to operand stack elif token == "(": op_stack.push(token) #look for closing braces ) elif token == ")": """ #1 closing - means end of scope #2 so we need to pop the stack #3 utill we get the corresponding open "(" #4 add all the appended operators to the output """ top_token = op_stack.pop() while top_token != "(": postfix_list.append(top_token) top_token = op_stack.pop() #for all other symbols else: #ie. for +,*,-./ # compare with all ops in the op_stack # find out if there is any operator with higher precedence # if yes add all of them to output # push to op_stack while not op_stack.is_empty(): #get operator oper = op_stack.peek() #get precedence oper_prec = prec[oper] #get precedence of current token token_prec = prec[token] #compare if oper_prec >= token_prec: #pop it oper = op_stack.pop() #add to output postfix_list.append(oper) #if op_stack is empty #push the operator to op_stack op_stack.push(token) #expression enumration complete #loop through opstack while not op_stack.is_empty(): #add them to output postfix_list.append(op_stack.pop()) #join the string return " ".join(postfix_list)
def infix_to_postfix1(infix_expr): #precedence table prec = {} prec["*"] = 3 prec["/"] = 3 prec["+"] = 2 prec["-"] = 2 prec["("] = 1 alaphabet_tokens = \ "ABCDEFGHIJKLMNOPQRSTUVWXYZ" numeral_tokens = \ "0123456789" #stack to hold operators op_stack = Stack() #list to hold operands #and final result postfix_list = [] #split the expression tokens_list = \ infix_expr.split() #enumerate for token in tokens_list: #check if token in alpabet or numeral_tokens if token in alaphabet_tokens or token in numeral_tokens: #push to postfix_list postfix_list.append(token) #check for open braces "(" #this is a operator elif token == "(": #add to op_stack op_stack.push(token) #check for closing braces ")" elif token == ")": """ 1. this is also an operator 2. indicating end of an expression 3. Logic to make an infix postfix is to move the operator to where the closing bracket is 4. this takes into account operator precedence 5. (A + B) * C for eg in postfix is AB+C* 6. A + (B * C) is ABC*+ """ #get operator op_from_stack = op_stack.pop() #pop the stack untill we get an open braces #which indicates beginning of the expression while not op_from_stack == "(": #append to the answer postfix_list.append(op_from_stack) #pop to continue while loop op_from_stack = op_from_stack.pop() #operator found (+,-,/,*) else: #push to op stack if it is empty if op_stack.is_empty(): op_stack.push(token) else: #loop while op_stack.is_empty(): #precedence comparison #if "token" precedence >= precedence of element in #stack # pop the stack and appane it to the output # if prec[token] >= prec[op_stack.peek()]: postfix_list.append(op_stack.pop()) #enumeration done #empty the op_stack # as we only emptied the ops with lesser precedence while not op_stack.is_empty(): postfix_list.append(op_stack.pop()) #make the String return " ".join(postfix_list)