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)
Пример #2
0
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()
Пример #4
0
    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()]
Пример #6
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)
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)
Пример #10
0
 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()
Пример #13
0
    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
Пример #14
0
    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
Пример #15
0
    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
Пример #16
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
Пример #17
0
    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())
Пример #18
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())
Пример #19
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
Пример #20
0
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
Пример #21
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
Пример #22
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)
Пример #23
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)