I have a script that iterates over 5 vectors of numbers and mixes them with all four operations that are looking for a combination that results in a specific target number.
The script prints the output, for example:
312 / 130 x 350 - 122 + 282 = 1000.0 312 / 130 x 350 + 282 - 122 = 1000.0 312 - 282 x 372 / 15 + 256 = 1000.0 142 + 350 - 372 x 125 / 15 = 1000.0 142 + 350 - 372 / 15 x 125 = 1000.0 350 / 130 x 312 + 282 - 122 = 1000.0 350 + 142 - 372 x 125 / 15 = 1000.0
Each line is formatted from a list of numbers and a list of operations.
What I would like to do is remove the equivalent results , i.e. have an output like:
312 / 130 x 350 - 122 + 282 = 1000.0 312 - 282 x 372 / 15 + 256 = 1000.0 142 + 350 - 372 x 125 / 15 = 1000.0
As a solution, at first I thought about โrememberingโ the numbers that already gave 1000, and skip them, but then I realized that this could obscure the new results, so I donโt know what to do.
How to find equivalent results for distribution and commutative laws?
Note: In the presented output, parentheses are NOT shown, but the order is reduced, which means, for example:
142 + 350 - 372 x 125 / 15 = 1000.0
calculated as:
(((142 + 350) - 372) x 125) / 15 = 1000.0
This is the code that I still have:
import operator from itertools import permutations, product, count from functools import reduce vectors = [[87, 125, 209, 312], [29, 122, 254, 372], [15, 130, 277, 369], [142, 197, 282, 383], [64, 157, 256, 350]] OPER = {operator.add: '+', operator.sub: '-', operator.mul: 'x', operator.truediv: '/'} def format_result(nums, ops, res): s = ' '.join('{} {}'.format(n,OPER[op]) for n,op in zip(nums, ops)) s += ' {} = {}'.format(nums[-1], res) return s def calc(vectors, test=lambda x: x == 1000.): for vv in permutations(vectors): for indexes in product((0,1,2,3), repeat=5): numbers = tuple(v[i] for i,v in zip(indexes, vv)) for operations in permutations(OPER): res = reduce(lambda x,y,n=count(0): operations[next(n)](x,y), numbers) if test(res): print(format_result(numbers, operations, res)) calc(vectors)