我有大范围的数字(从10 ^ 5到10 ^ 6)我需要计算所有数字的总和与产品相同的数字。
例如,111126
我尝试使用以下代码,因为数字范围很广,所以效果很好,但速度很慢。
result = 0
for num in range(x, y):
num_str = str(num)
summation = 0
product = 1
for j in range(len(num_str)):
summation += int(num_str[j])
product *= int(num_str[j])
if j == len(num_str) - 1:
if summation == product:
result += 1
print(result)
有没有办法在不使用循环的情况下计算这些数字?如果没有,如何让它运行得更快?
答案 0 :(得分:3)
您根本不需要暴力破解,因为您可以大幅限制搜索。
1 + 2
的总和与2 + 1
相同,这同样适用于他们的产品。最好将注意力集中在具有相等或递增数字的数字上,如果这些数字总和与产品相同的值,则可以获取这些数字的所有唯一排列。
要生成候选数字,只有1287个排列,从1到9的5位数替换:
>>> import itertools
>>> len(list(itertools.combinations_with_replacement(range(1, 10), 5)))
1287
这是一个小得多的搜索空间:
from itertools import combinations_with_replacement, permutations
from operator import mul
from functools import reduce
results = set()
for digits in combinations_with_replacement(range(1, 10), 5):
if sum(digits) == reduce(mul, digits):
# add unique permutations of the digits as a new integer
results.update(int(''.join(map(str, p))) for p in permutations(digits))
for result in sorted(results):
print(result)
这确实在很短的时间内产生了40个结果:
>>> from itertools import combinations_with_replacement, permutations
>>> from operator import mul
>>> from functools import reduce
>>> results = set()
>>> for digits in combinations_with_replacement(range(1, 10), 5):
... if sum(digits) == reduce(mul, digits):
... results.update(int(''.join(map(str, p))) for p in permutations(digits))
...
>>> len(results)
40
>>> for result in sorted(results):
... print(result)
...
11125
11133
11152
11215
11222
11251
11313
11331
11512
11521
12115
12122
12151
12212
12221
12511
13113
13131
13311
15112
15121
15211
21115
21122
21151
21212
21221
21511
22112
22121
22211
25111
31113
31131
31311
33111
51112
51121
51211
52111
搜索可能会进一步缩小;如果有更多mathematical observations,您可以缩小搜索范围至少为2 1
位数的数字,但上述情况已经非常快了。
答案 1 :(得分:0)
加速循环的常用方法是将它们更改为numpy数组,并执行数组操作而不是循环。因此,如果您将数字放入2D numpy数组中然后执行数组操作(例如A == B)并计算新数组中的trues,则通常会更快。
也许有比蛮力更好的方法。我不清楚你的范围,因为你给出的例子超出你给出的范围,但你可以看到最大总和是5x9 = 45.你可以立即删除任何总和大于10的总和。
例如,您可以浏览5个数字 a,b,c,d,e 的所有不同产品,例如 1< = b< = c< = d< ; = e< = 9 和 abced< = 45 。当您找到解决方案时,只需计算出与您找到的解决方案相似的其他类似解决方案的数量。