Full app below.
Works with any formula length.
Parenthesis give order of operators, so we test all combinations.
Testing all permutations of n operators is n!
with 3 operators as in sample it's 6 tests.
for 8 operators, it will be 40320 ...
The code doesn't stop when the searched value is found as it could be several manner to obtain the same result.
All possible results are shown at the end.
For the given formula : ---- all possible results : {1, 7, 10, -14, -5}
Enjoy
from itertools import permutations
formula = [6,'-',4,'*',2,'+',3] ;
searchedValue = 10 ;
# operators are on odd positions .
operatorsPositions = list(range(1,len(formula),2)) # [1, 3, 5]
# prepare all permutations eq all parenthesis order . return an array of tuple
permut = list(permutations(operatorsPositions))
print("**** {0} permutations to be tested ****".format(len(permut)))
print(permut)
# around an operator , two operands . return result
def calcAround(aFormula,position):
op1 = aFormula[position -1]
op2 = aFormula[position +1]
operator = aFormula[position]
# optional trace operation
# print("calculate ({0:2d} {1} {2:2d})".format(op1,operator,op2));
if (operator == "-"): return op1-op2;
if (operator == "+"): return op1+op2;
if (operator == "*"): return op1*op2;
if (operator == "/"): return op1/op2;
#--------------------
# 'op1', 'operator', 'op2' replaced by result in formula
def reduceAtPosition(someformula,position):
result = calcAround(someformula,position);
formulaNew =[];
for i in range (0,position-1): formulaNew.append(someformula[i]);
formulaNew.append(result);
for i in range (position+2,len(someformula)):formulaNew.append(someformula[i]);
return formulaNew;
# ------- main part --------
# set to store unique possible results
allResults = set(())
# try each permutation of operators order
for aTest in permut:
aPermut = list(aTest) # better to have an array in place of tuple
print('----------------')
# make a new copy each tour
lTempo = formula.copy()
print("operators sequence: {0}".format(aPermut))
while(len(aPermut)>0):
print(lTempo)
anOpIndice = aPermut[0]
lTempo = reduceAtPosition(lTempo,anOpIndice);
# remove first done
aPermut = aPermut[1:]
for i in range(0,len(aPermut)):
if (aPermut[i]>anOpIndice): aPermut[i] -= 2
#
final = lTempo[0]
print("result: {0}".format(final))
# to respond to question
if(final == searchedValue):
print('*** found {0} with order or operators positions: {1} '.format(final,aTest))
allResults.add(final)
print('---- all possible results : {0}'.format(allResults))
Console results:
**** 6 permutations to be tested ****
[(1, 3, 5), (1, 5, 3), (3, 1, 5), (3, 5, 1), (5, 1, 3), (5, 3, 1)]
----------------
operators sequence: [1, 3, 5]
[6, '-', 4, '*', 2, '+', 3]
[2, '*', 2, '+', 3]
[4, '+', 3]
result: 7
----------------
operators sequence: [1, 5, 3]
[6, '-', 4, '*', 2, '+', 3]
[2, '*', 2, '+', 3]
[2, '*', 5]
result: 10
*** found 10 with order or operators positions: (1, 5, 3)
----------------
operators sequence: [3, 1, 5]
[6, '-', 4, '*', 2, '+', 3]
[6, '-', 8, '+', 3]
[-2, '+', 3]
result: 1
----------------
operators sequence: [3, 5, 1]
[6, '-', 4, '*', 2, '+', 3]
[6, '-', 8, '+', 3]
[6, '-', 11]
result: -5
----------------
operators sequence: [5, 1, 3]
[6, '-', 4, '*', 2, '+', 3]
[6, '-', 4, '*', 5]
[2, '*', 5]
result: 10
*** found 10 with order or operators positions: (5, 1, 3)
----------------
operators sequence: [5, 3, 1]
[6, '-', 4, '*', 2, '+', 3]
[6, '-', 4, '*', 5]
[6, '-', 20]
result: -14
---- all possible results : {1, 7, 10, -14, -5}