I need to code a program that can get values from strings like this
abs(add(add(9465,38),multiply(add(63303,146),46)))
The format works as, add(x,y) = x+y
, sub(x,y) = x-y
, multiply(x,y) = x*y
, abs
returns absolute value but that is simpler.
I am confused at first how to break the string and then after that how I am going to break at parenthesis pairs to follow order of operations.
Interesting problem, here is a potential solution. No doubt you could make a much more elegant solution using libraries or lambdas etc. as thefourtheye did in their answer, but this seems to work.
I have done a few test cases at the bottom, set the global verbose
to True
if you want debug info:
# globals
verbose = False # set to True if you want debug info printed
max_iter = 1000 # this stops infinate loops incase the code does not allow for some input
def solve(problem_str):
def multiply(arg_list):
x = 1
for i in arg_list:
x *= i
return x
def find_innermost(x_str):
a, b, c, i = [0], [0], 0, 0
while True:
i += 1
start = a[-1]+1
a.append(x_str.find('(', start)) # find next (
b.append(x_str.find(',', start)) # find next ,
c = x_str.find(')', start) # find next )
if (a[-1] > c) or (a[-1] == -1):
if (b[-2] > a[-3]) and (b[-2] < a[-2]):
return x_str[b[-2]+1:c+1]
else:
return x_str[a[-3]+1:c+1]
if i >= max_iter:
raise Exception("Infinite loop")
def do_sum(x_str):
args = [int(x) for x in x_str[x_str.find('(')+1:x_str.find(')')].split(',')]
task = x_str[:3].lower()
if task == 'add':
return sum(args)
elif task == 'sub':
return args[0] - sum(args[1:])
elif task == 'abs':
return abs(args.pop())
elif task == 'mul':
return multiply(args)
else:
print x_str + ': Task not recognised, please modify program or input'
raise Exception("Invalid input")
i = 0
while True:
i += 1
if verbose: print 'debug: problem_str:', problem_str
if problem_str.count('(') > 1:
x_str = find_innermost(problem_str)
else:
x_str = problem_str
if verbose: print '.'*6, 'x_str:\t', x_str
x = do_sum(x_str)
if verbose: print '.'*6, 'x:\t', x, '\n'
problem_str = problem_str.replace(x_str, str(x))
if problem_str.count('(') == 0:
return int(problem_str)
if i >= max_iter:
raise Exception("Infinite loop")
if __name__ == '__main__':
p1 = 'abs(add(add(9465,38),multiply(add(63303,146),46)))'
p2 = 'abs(add(multiply(95,multiply(-1,multiply(13,18875))),multiply(-1,add(18293,26))))'
p3 = 'abs(add(subtract(add(add(151,26875),122),254),subtract(237,multiply(-1,56497))))'
r1, r2, r3 = solve(p1), solve(p2), solve(p3)
print 'p1 evaluates to:', r1
print 'p2 evaluates to:', r2
print 'p3 evaluates to:', r3
Let me know if you have any questions about the code.