用一串数字生成加法、减法或什么都不做的变化,使 100

问题描述

我有一串数字,string="123456789",我想打印所有变体,在数字之间插入加法、减法或什么都不做,得到 100。大多数数字的顺序保持不变。

示例:1+2+3-4+5+6+78+9=100

我什至不知道如何开始。我想列出所有可能的 +-x 组合(x 代表无)并插入每个组合并进行测试,但这似乎需要很长时间。 有什么建议吗?

解决方法

您可以使用 itertools 模块中的 productzip_longest 来实现。我们建立所有可能的组合,然后evaluate 只过滤那些评估为 100 的组合。

from itertools import product,zip_longest

operations = ['-','+','']
s = '123456789'

combinations = (zip_longest(s,ops,fillvalue='') for ops in product(operations,repeat=8))

to_eval = (''.join(i + j for i,j in combination) for combination in combinations)

print([i for i in to_eval if eval(i) == 100])

>>> ['1+2+3-4+5+6+78+9','1+2+34-5+67-8+9','1+23-4+5+6+78-9','1+23-4+56+7+8+9','12-3-4+5-6+7+89','12+3-4+5+67+8+9','12+3+4+5-6-7+89','123-4-5-6-7+8-9','123-45-67+89','123+4-5+67-89','123+45-67+8-9']

eval() 本质上并不坏,只是如果任何用户输入可以进入您正在评估的东西(这里不是这种情况),它就会导致重大的安全问题。为个人项目执行此操作很好。在生产环境中,您可能希望自己解析字符串或寻找不同的方法。

优化说明请看这里:Most pythonic way to interleave two strings

,
a = ['+','-','']
nb = '123456789'
target = 100
N = len(nb)-1

for n in range(3**N):
    attempt = nb[0]
    for i in range(N):
        attempt += a[n % 3]
        attempt += nb[i+1]
        n = n // 3
    if eval(attempt) == target:
        print(attempt,' = ',target)

导致

1+23-4+56+7+8+9  =  100
12+3-4+5+67+8+9  =  100
1+2+34-5+67-8+9  =  100
1+2+3-4+5+6+78+9  =  100
123-4-5-6-7+8-9  =  100
123+45-67+8-9  =  100
1+23-4+5+6+78-9  =  100
12-3-4+5-6+7+89  =  100
12+3+4+5-6-7+89  =  100
123-45-67+89  =  100
123+4-5+67-89  =  100