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()]
Пример #2
0
    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)
Пример #5
0
    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)
Пример #6
0
 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())
Пример #7
0
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)
Пример #8
0
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()
Пример #11
0
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
Пример #12
0
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)
Пример #13
0
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)
Пример #14
0
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