-7

enter image description here

I got the python code below that solves the expression above. I believe there should be a more generic Pythonic approach. By generic I mean it should solve any combinations of numbers (not just: 2 ** 2 ** 2 ** 2 ** 0) e.g: 3 ** 2 ** 4 ** 1 ** 0, 3 ** 3 ** 1 ** 2 ** 0 etc

def get_expo(expo, index, cur_expo):
    return int(expo[index-1]) ** cur_expo


def solve_expo(expo):
    expo = expo.split("^")
    index = len(expo) - 1
    cur_expo = int(expo[-1])
    result = 0
    for i in range(len(expo)):
        if index == 1:
            result = get_expo(expo, index, cur_expo)
            return "Answer is: " + str(result)
        else:
            cur_expo = get_expo(expo, index, cur_expo)
            index -= 1



print solve_expo("2^2^2^2^0")

I need a better pythonic approach to solving it?

Morgan Thrapp
  • 9,748
  • 3
  • 46
  • 67
Umar Yusuf
  • 926
  • 2
  • 13
  • 30

3 Answers3

2

Python's built-in ** operator respects precedence correctly already. You can feed it the full expression and get the answers you are expecting.

>>> 3 ** 2 ** 4 ** 1 ** 0
43046721

So the straightforward (but potentially dangerous) way to write your function is something like this, by just evaluating the expression after replacing the ^ with **:

def solve_expo(expression):
    return eval(expression.replace('^', '**'))

Obviously, eval might not be suitable for your situation (or you might just want to do something a little more interesting), so you could rewrite your solution as a recursive one. It's a little more elegant, at any rate.

def solve_expo(expression):
    base, exp = expression.split('^', 1)  # Split off just the first ^
    if '^' in exp:
        return int(base) ** solve_expo(exp)  # More exponents later, so resolve them and raise our base to that power
    return int(base) ** int(exp)  # base and exp are plain numbers, so just return base^exp
Community
  • 1
  • 1
Henry Keiter
  • 16,863
  • 7
  • 51
  • 80
1

Alternative approach to achieve this by using reduce() function as:

>>> operation_str = '3^2^4^1^0'
>>> reduce(lambda x, y: int(y)**int(x), operation_str.split('^')[::-1])
43046721

Explanation based on step by step operation:

>>> operation_str.split('^')
['3', '2', '4', '1', '0'] # Converted str into list
>>> operation_str.split('^')[::-1]
['0', '1', '4', '2', '3'] # Reversed list
>>> reduce(lambda x, y: int(y)**int(x), operation_str.split('^')[::-1])
43046721  # Check reduce() fucntion linked above to know how it works

Also read: Why should exec() and eval() be avoided?

Community
  • 1
  • 1
Moinuddin Quadri
  • 46,825
  • 13
  • 96
  • 126
0

Since you want to handle it as a recursion, this code seems to handle it nicely. The split creates a single list of string values which are then handled completely within the recursive function.

val = '2^3^4^5^6^7'
vals = val.split('^')

def solve_expo(expo):
    if len(expo) == 1:
        return int(expo)
    else:
        return solve_expo(expo[:-1]) ** int(expo[-1])

solv_expo(vals)
sabbahillel
  • 4,357
  • 1
  • 19
  • 36