[英]Finding all possible permutations of an unfixed length of numbers to reach a given sum or product
Using plain Python or any Python libraries, how would you go about finding all possible combinations of elements in a list l
that equal a given value val
using addition , subtraction , or multiplication ?使用普通的 Python 或任何 Python 库,您将如何使用 go 查找列表
l
中等于给定值val
的所有可能的元素组合、加法或乘法? Assume the length of the list isn't always the same, assume each element in the list can only be used once in each combination, and assume there isn't any use of parentheses.假设列表的长度并不总是相同,假设列表中的每个元素在每个组合中只能使用一次,并且假设没有使用任何括号。
For example:例如:
l = [1,2,3,4]
l = [1,2,3,4]
val = 6
val = 6
[2,4]
, since 2+4=6
[2,4]
,因为2+4=6
[4,2]
, since 4+2=6
[4,2]
,因为4+2=6
[1,3,2]
, since 1+3+2=6
[1,3,2]
,因为1+3+2=6
[1,2,4]
, since 1*2+4=6
[1,2,4]
,因为1*2+4=6
I've tried using itertools.permutations :我试过使用itertools.permutations :
>>> from itertools import permutations
>>> l = [1,2,3,4]
>>> val = 6
>>> correct_combos = []
>>> for i in range(1, len(l)+1):
... for p in permutations(l, r=i):
... if sum(p) == val:
... correct_combos.append(p)
I'm able to only implement the code for testing the sum of all combinations of elements in the list.我只能实现代码来测试列表中所有元素组合的总和。
>>> print(correct_combos)
[(2, 4), (4, 2)]
I'm stuck on finding permutations of elements in the list using a combination of addition, subtraction, and multiplication.我一直坚持使用加法、减法和乘法的组合来查找列表中元素的排列。
I don't know if this algorithm is efficient, but it works fine:我不知道这个算法是否有效,但它工作正常:
from itertools import permutations, product
l = [1,2,3,4]
val = 6
operator = ['+', '-', '*']
correct_combos=[]
for r in range(1, len(l)+1):
for item in permutations(l,r):
for unit in product(operator, repeat=r-1):
res=""
for idx in range(0,r-1):
res+=str(item[idx])+unit[idx]
res+=str(item[-1])
if(val==eval(res)):
if item not in correct_combos:
correct_combos.append(item)
print(correct_combos)
Output Output
[(2, 3), (2, 4), (3, 2), (4, 2), (1, 2, 3), (1, 2, 4), (1, 3, 2), (1, 4, 2), (2, 1, 3), (2, 1, 4), (2, 3, 1), (2, 4, 1), (3, 1, 2), (3, 1, 4), (3, 2, 1), (3, 4, 1), (4, 1, 2), (4, 1, 3), (4, 2, 1), (4, 3, 1), (1, 2, 3, 4), (1, 2, 4, 3), (1, 3, 2, 4), (1, 3, 4, 2), (1, 4, 2, 3), (1, 4, 3, 2), (2, 4, 1, 3), (2, 4, 3, 1), (3, 1, 2, 4), (3, 1, 4, 2), (3, 2, 1, 4), (3, 2, 4, 1), (3, 4, 1, 2), (3, 4, 2, 1), (4, 1, 2, 3), (4, 1, 3, 2), (4, 2, 1, 3), (4, 2, 3, 1), (4, 3, 1, 2), (4, 3, 2, 1)]
You can use a recursive generator function:您可以使用递归生成器 function:
from operator import add, sub, mul
l = [1,2,3,4]
val = 6
def combos(c = [], r_exp = None):
if r_exp == val:
yield c
else:
for i in filter(lambda x:x not in c, l):
if not c:
yield from combos(c=[i], r_exp = i)
else:
for s, f in [['+', add], ['-', sub], ['*', mul]]:
yield from combos(c=c+[s, i], r_exp = f(r_exp, i))
print([''.join(map(str, i)) for i in combos()])
Output: Output:
['1+2+3', '1-2+3+4', '1-2+4+3', '1*2*3', '1*2+4', '1+3+2', '1+3-2+4', '1+3+4-2', '1*3*2', '1+4-2+3', '1+4+3-2', '1*4+2', '1*4-2*3', '2+1+3', '2*1*3', '2*1+4', '2+3+1', '2*3', '2+4', '2*4+1-3', '2*4-3+1', '3+1+2', '3+1-2+4', '3+1+4-2', '3-1+4', '3-1*4-2', '3*1*2', '3+2+1', '3-2+1+4', '3-2+4+1', '3*2', '3+4+1-2', '3+4-1', '3+4-2+1', '4+1-2+3', '4+1+3-2', '4-1*2', '4-1+3', '4*1+2', '4*1-2*3', '4+2', '4-2+1+3', '4-2*1*3', '4-2+3+1', '4-2*3', '4*2+1-3', '4*2-3+1', '4+3+1-2', '4+3-1', '4+3-2+1']
To just get the tuple results, only a small change needs to be made:为了得到元组结果,只需要做一个小的改变:
for f in [add, sub, mull]:
yield from combos(c=c+[i], r_exp = f(r_exp, i))
...
print(list(map(tuple, combos())))
Output: Output:
[(1, 2, 3), (1, 2, 3, 4), (1, 2, 4, 3), (1, 2, 3), (1, 2, 4), (1, 3, 2), (1, 3, 2, 4), (1, 3, 4, 2), (1, 3, 2), (1, 4, 2, 3), (1, 4, 3, 2), (1, 4, 2), (1, 4, 2, 3), (2, 1, 3), (2, 1, 3), (2, 1, 4), (2, 3, 1), (2, 3), (2, 4), (2, 4, 1, 3), (2, 4, 3, 1), (3, 1, 2), (3, 1, 2, 4), (3, 1, 4, 2), (3, 1, 4), (3, 1, 4, 2), (3, 1, 2), (3, 2, 1), (3, 2, 1, 4), (3, 2, 4, 1), (3, 2), (3, 4, 1, 2), (3, 4, 1), (3, 4, 2, 1), (4, 1, 2, 3), (4, 1, 3, 2), (4, 1, 2), (4, 1, 3), (4, 1, 2), (4, 1, 2, 3), (4, 2), (4, 2, 1, 3), (4, 2, 1, 3), (4, 2, 3, 1), (4, 2, 3), (4, 2, 1, 3), (4, 2, 3, 1), (4, 3, 1, 2), (4, 3, 1), (4, 3, 2, 1)]
Non recursive solution:非递归解决方案:
from itertools import permutations, product, accumulate
from collections import deque
from operator import add, sub, mul
l = [1, 2, 3, 4]
val = 6
correct_combos = []
def is_correct(p, val, ops=[add, sub, mul]):
if len(p) == 1:
return p[0] == val
for op in product(ops, repeat=len(p) - 1):
iop = iter(op)
l = deque(accumulate(p, lambda a, b: next(iop)(a, b)), maxlen=1)[0]
if l == val:
return True
return False
for i in range(1, len(l) + 1):
for p in permutations(l, r=i):
if is_correct(p, val):
correct_combos.append(p)
print(correct_combos)
Prints:印刷:
[(2, 3), (2, 4), (3, 2), (4, 2), (1, 2, 3), (1, 2, 4), (1, 3, 2), (1, 4, 2), (2, 1, 3), (2, 1, 4), (2, 3, 1), (2, 4, 1), (3, 1, 2), (3, 1, 4), (3, 2, 1), (3, 4, 1), (4, 1, 2), (4, 1, 3), (4, 2, 1), (4, 2, 3), (4, 3, 1), (1, 2, 3, 4), (1, 2, 4, 3), (1, 3, 2, 4), (1, 3, 4, 2), (1, 4, 2, 3), (1, 4, 3, 2), (2, 4, 1, 3), (2, 4, 3, 1), (3, 1, 2, 4), (3, 1, 4, 2), (3, 2, 1, 4), (3, 2, 4, 1), (3, 4, 1, 2), (3, 4, 2, 1), (4, 1, 2, 3), (4, 1, 3, 2), (4, 2, 1, 3), (4, 2, 3, 1), (4, 3, 1, 2), (4, 3, 2, 1)]
from itertools import chain, combinations
def subSet(l):
return chain.from_iterable(combinations(l, r) for r in range(len(l) + 1))
def whatWeWant(l, val):
x = 0
for i in l:
x += i
if x == val:
return True
return False
l = [1, 2, 3, 4]
val = 6
allSubSets = list(subSet(l))
ans = []
for subSet in allSubSets:
if whatWeWant(subSet, val):
ans.append(subSet)
With this code you can find what you want but you have to specifically say the possible combinations(in whatWeWant method).使用此代码,您可以找到所需的内容,但您必须明确说明可能的组合(在 whatWeWant 方法中)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.