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 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 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 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 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 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 stack_boxes(boxes, stack=None): """ :param boxes: dict of tuples {box_num : (length, width, height)} :return: height of largest stack """ if len(boxes.keys()) == 0: return 0 if stack is None: stack = Stack() heights = [0] for key in tuple(boxes.keys()): if stack.peek() is None or tuple_greater(stack.peek(), boxes[key]): height = 0 stack.push(boxes[key]) del boxes[key] heights.append(stack.peek()[2] + stack_boxes(boxes, stack)) boxes[key] = stack.pop() return max(heights)
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 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 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 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)
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 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