繁体   English   中英

列表与特定总和的组合

[英]Combination of lists with a specific sum

我想使用python解决此问题:

以数字顺序将数字1,2,3乘以9,并在数字之间加上一个加号或一个减号,或两者都不加,以使总和达到100。例如,一种实现方法是:1 + 2 + 34-5 + 67-8 + 9 = 100,其中使用了六个加减。 您需要做的最少的正负次数是多少?

我考虑过要从生成有效的元组开始,例如(1,2,34,567,89),然后确定哪些元组加起来为100,然后找到最短的元组。

为此,我首先创建了可能的数字列表(数十和数百),因为我敢肯定没有4位数字的组合。

strnumbers = [str(x) for x in range(1,10)]
digits = [int(i) for i in strnumbers]
tens = [int(strnumbers[a] + strnumbers[a+1]) for a in range(8)]
hundreds = [int(strnumbers[a] + strnumbers[a+1] + strnumbers[a+2]) for a in range(7)]

但是,我不确定如何创建实际的可能列表。

我的问题有两个:

  1. 您将如何使用十位数和百位数来创建可能的元组?

  2. 就计算而言,这是否合理? 感觉就像我在做很多额外的工作

import itertools

results = []
for opers in itertools.product(('-','+',''),repeat=8):
    expression = '1{}2{}3{}4{}5{}6{}7{}8{}9'.format(*opers)
    result = eval(expression)
    if result == 100:
        results.append(expression)
best_result = min(results, key=len)
print(best_result, len(best_result)-9)

这是一种解决类似问题的方法。 您没有显示足够的代码来让我显示完整的解决方案,因此这是构想的概述。 这种方法与您的方法不同,但是您不必担心每个术语的位数。

  1. 您希望数字之间有一些其他字符,所以请考虑字符串'1{}2{}3{}4{}5{}6{}7{}8{}9'
  2. 使用itertools.product()获得使用'+''-'''填充大括号的所有可能方法。 您需要八个短字符串。 产品总数将为3**8 == 6561 ,这对于Python程序来说是很小的数目。
  3. 对于每种可能的产品,使用产品上字符串的format()方法创建一个完整的表达式。
  4. 使用eval()计算该表达式的值。 使用eval()通常很危险,但是由于仅在构造的字符串上使用它就没有问题。
  5. 将值与100进行比较,并存储产生该值的字符串。
  6. 收集完所有琴弦后,找到长度最短的琴弦。 那将有最少的优点和缺点。
  7. 从最短的长度中减去9的位数,然后打印出来,就可以了。

可以将步骤5到7组合在一起,以减少内存使用量。 使用product作为生成器并对其进行循环(而不是从中进行列表),还可以降低内存使用量。

我会以不同的方式处理这个问题。 您有数字列表:

digits = [1, 2, 3, 4, 5, 6, 7, 8, 9]

因此,您必须对如何连接数字做出8个决定(如果允许在数字1之前加上减号,则必须做出9个决定,但我认为这里不是)。 对于这些决定中的每一个,您都有三个选择:加,减或都不(联接)。 因此,有3 ^ 8个选择。 我只是迭代他们以找到最好的一个:

from itertools import product

digits = [1, 2, 3, 4, 5, 6, 7, 8, 9]
options = ["", "+", "-"]
number = 100
best_sol_str = ""
best_sol_cost = 10  # Or infinity
for sol in product(*([options] * 8)):  # `* 9` if starting with "-" allowed
    factor = 1
    current = 0
    total = 0
    sol_cost = 0
    sol_str = ""
    # Remove `("",) + ` if used `* 9` before
    for opt, d in zip(("",) + sol, digits):  
        sol_str += opt + str(d)
        if opt == "":
            current = current * 10 + d
        else:
            total += factor * current
            current = d
            sol_cost += 1
            if opt == "+":
                factor = 1
            elif opt == "-":
                factor = -1
    total += factor * current
    if total == number and sol_cost < best_sol_cost:
        best_sol_str = sol_str
        best_sol_cost = sol_cost

print("Best solution: {}={} ({} operations).".format(
    best_sol_str, number, best_sol_cost))

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM