[注:编程挑战]
挑战说明:
输入:数字列表1,5,6,2,7,4 非重复且无零(数字1-9全部有效)。目标是创建所有排列并将它们全部加起来。我为此使用了itertools排列。我能够在本地机器上用7,8和9digits做一些测试断言。在9位数时,服务器在12秒内超时的时间会增加很多,但我的计算机不会花那么长时间。它只是说要优化我的算法。
下面是如何形成数组的示例,itertools在内部循环的每次迭代中执行此操作。
array for the list sum (terms of arrays)
[1] 1 # arrays with only one term (7 different arrays)
[5] 5
[6] 6
[2] 2
[7] 7
[3] 3
[4] 4
[1, 5] 6 # arrays with two terms (42 different arrays)
[1, 6] 7
[1, 2] 3
[1, 7] 8
[1, 3] 4
[1, 4] 5
..... ...
[1, 5, 6] 12 # arrays with three terms(210 different arrays)
[1, 5, 2] 8
[1, 5, 7] 13
[1, 5, 3] 9
........ ...
这是我到目前为止所做的,它完成了工作,但我的主要瓶颈是总和,从8位到9位数呈指数增长。功能 传递 两个测试,但在服务器上超时。
for i in range(1, limit + 1):
for j in permutations(digits, i):
grandSum =+ grandSum + sum(j)
以下是cProfile运行的结果,7,8,9:
13778 function calls in 0.011 seconds
Ordered by: standard name
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.000 0.000 0.011 0.011 <string>:1(<module>)
7 0.000 0.000 0.000 0.000 GreatTotalAdditions.py:25(removefirstindex)
1 0.006 0.006 0.011 0.011 GreatTotalAdditions.py:31(gta)
1 0.000 0.000 0.011 0.011 {built-in method builtins.exec}
21 0.000 0.000 0.000 0.000 {built-in method builtins.len}
8 0.000 0.000 0.000 0.000 {built-in method builtins.print}
13699 0.004 0.000 0.004 0.000 {built-in method builtins.sum}
25 0.000 0.000 0.000 0.000 {method 'append' of 'list' objects}
1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects}
7 0.000 0.000 0.000 0.000 {method 'insert' of 'list' objects}
7 0.000 0.000 0.000 0.000 {method 'pop' of 'list' objects}
109701 function calls in 0.086 seconds
Ordered by: standard name
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.000 0.000 0.085 0.085 <string>:1(<module>)
11 0.000 0.000 0.000 0.000 GreatTotalAdditions.py:25(removefirstindex)
1 0.047 0.047 0.085 0.085 GreatTotalAdditions.py:31(gta)
1 0.000 0.000 0.086 0.086 {built-in method builtins.exec}
27 0.000 0.000 0.000 0.000 {built-in method builtins.len}
9 0.000 0.000 0.000 0.000 {built-in method builtins.print}
109600 0.038 0.000 0.038 0.000 {built-in method builtins.sum}
28 0.000 0.000 0.000 0.000 {method 'append' of 'list' objects}
1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects}
11 0.000 0.000 0.000 0.000 {method 'insert' of 'list' objects}
11 0.000 0.000 0.000 0.000 {method 'pop' of 'list' objects}
986553 function calls in 0.701 seconds
Ordered by: standard name
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.000 0.000 0.701 0.701 <string>:1(<module>)
16 0.000 0.000 0.000 0.000 GreatTotalAdditions.py:25(removefirstindex)
1 0.374 0.374 0.701 0.701 GreatTotalAdditions.py:31(gta)
1 0.000 0.000 0.701 0.701 {built-in method builtins.exec}
34 0.000 0.000 0.000 0.000 {built-in method builtins.len}
10 0.000 0.000 0.000 0.000 {built-in method builtins.print}
986409 0.327 0.000 0.327 0.000 {built-in method builtins.sum}
48 0.000 0.000 0.000 0.000 {method 'append' of 'list' objects}
1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects}
16 0.000 0.000 0.000 0.000 {method 'insert' of 'list' objects}
16 0.000 0.000 0.000 0.000 {method 'pop' of 'list' objects}
以下是我需要帮助的地方: 知道总和占用了大部分计算时间。我想出了这个数学公式,一个3位数字的例子:
(3-1)! *(1 + 2 + 3)*(111)
我的实现如下,请记住我是python的新手:
def sum_them_quick(digits):
ones = ""
digitsSum = 0
# if 3 digits then form 111
for i in range(len(digits)):
ones += "1"
for j in digits:
digitsSum = digitsSum + j
return factorial(len(digits)-1) * (digitsSum) * (int(ones))
然而,最后一个函数的结果是错误的,并且与通过的测试的良好结果不对应。我不完全确定排列的数量是否与itertools排列方法不同,但我明天肯定会确认。