def evaluate_infix(infix_expression):
    """
    Evaluates an infix expression.
    Numerical operands must be integers.

    >>> evaluate_infix('2 + 3 * 4')
    14
    >>> evaluate_infix('2 + (3 * 4)')
    14
    >>> evaluate_infix('(2 + 3) * 4')
    20
    >>> evaluate_infix('2 + 3 * 2 - 5')
    3
    >>> evaluate_infix('(2 + 3) * (2 - 5)')
    -15
    >>> evaluate_infix('(2 + 3) * (5 / 2)')
    12.5
    """

    # Split infix string into tokens. For example:
    #  '2+3*4' => ['2', '+', '3', '*', '4']
    tokens = re.findall(r'(\d+|\*|\+|\/|\-|\)|\(|\^)', infix_expression)

    operator = Stack()
    operand = Stack()
    for s in tokens:
        if s not in OP_PREC:  #s is an integer
            operand.push(s)
        elif s == '(':
            operator.push(s)
        elif s == ')':
            item = operator.pop()
            while item != '(':
                alpha = float(operand.pop())
                beta = float(operand.pop())
                if item == '(':
                    operator.pop()
                else:
                    delta = calculate(item, beta, alpha)
                    operand.push(delta)
                item = operator.pop()
        else:  #s is an operator
            if len(operator) > 1 and len(operand) > 2:
                if OP_PREC[s] < OP_PREC[operator.peek()]:
                    sign = operator.pop()
                    alpha = float(operand.pop())
                    beta = float(operand.pop())
                    delta = calculate(sign, beta, alpha)
                    operand.push(delta)
            operator.push(s)
    while not operand.is_empty() and not operator.is_empty():
        sign = operator.pop()
        alpha = float(operand.pop())
        beta = float(operand.pop())
        delta = calculate(sign, beta, alpha)
        operand.push(delta)
    result = operand.pop()
    if result % int(result) == 0:
        result = round(result)
    return result
def infix_to_postfix(infix_expression):
    """
    Converts an infix expression to a postfix expression.
    Numerical operands must be integers.

    >>> infix_to_postfix('2 + 3')
    '2 3 +'
    >>> infix_to_postfix('2 + 3 * 4')
    '2 3 4 * +'
    >>> infix_to_postfix('(2 + 3) * 4')
    '2 3 + 4 *'
    >>> infix_to_postfix('2 + 3 * 2 - 5')
    '2 3 2 * + 5 -'
    >>> infix_to_postfix('(2 + 3) * (2 - 5)')
    '2 3 + 2 5 - *'
    >>> infix_to_postfix('(2 + 3) * (5 / 2)')
    '2 3 + 5 2 / *'
    """

    # Split infix string into tokens. For example:
    #  '2+3*4' => ['2', '+', '3', '*', '4']
    tokens = re.findall(r'(\d+|\*|\+|\/|\-|\)|\(|\^)', infix_expression)

    output = []
    stack = Stack()
    for s in tokens:
        if s not in OP_PREC:
            output.append(s)
        elif s == '(':
            stack.push(s)
        elif s == ')':
            item = stack.pop()
            while item != '(':
                output.append(item)
                item = stack.pop()
        else:
            while not stack.is_empty() and OP_PREC[s] <= OP_PREC[stack.peek()]:
                output.append(stack.peek())
                stack.pop()
            stack.push(s)
    while not stack.is_empty():
        output.append(stack.pop())
    string = ''
    count = 0
    for i in range(len(output) - 1):
        string += output[i]
        string += ' '
        count += 1
    string += output[-1]
    return string
Ejemplo n.º 3
0
    def depth_first_search(self, board):

        moves = ['Up', 'Down', 'Left', 'Right'][::-1]
        frontier = Stack()
        explored = set()

        frontier.push(State(board))
        nodes_expanded = 0

        while not frontier.is_empty():
            curr = frontier.pop()
            explored.add(curr)

            if curr.board == self.goalBoard:
                return curr, nodes_expanded

            nodes_expanded += 1

            for move in moves:
                result = curr.board.move(move)
                if result is not None:
                    result_state = State(result, move, curr, curr.depth + 1)
                    if result_state not in explored and result_state not in frontier:
                        State.max_depth = max(State.max_depth, result_state.depth)
                        frontier.push(result_state)