我正在使用Project Euler problem 12
第一个三角形数的值超过500个除数是多少?
我确信它可以为较小的数字产生正确的答案。例如,如果我将> 500
替换为== 6
,则我得到的输出结果是预期的28
。
对于500个除数,大约两分钟执行,程序开始运行得非常慢。我相信这里的每个变量都会在每次迭代时被覆盖。它为什么慢?我已经尝试分离成函数来使用局部变量,但这并没有改善运行时间。
代码:
import sys
currentNumber, currentCalculationNumber, divisorCount, naturalNumber = 1, 1, 0, 1
while True:
while currentCalculationNumber <= currentNumber:
if currentNumber % currentCalculationNumber == 0:
divisorCount += 1
currentCalculationNumber += 1
if divisorCount > 500:
print ("ANSWER: " , currentNumber)
sys.exit(0)
naturalNumber += 1
currentNumber += naturalNumber
currentCalculationNumber, divisorCount = 1, 0
答案 0 :(得分:3)
缓慢来自你的计算除数的蛮力方法。解决方案大约为10 ^ 8,因此您需要以10 ^ 16次的顺序遍历内部while
循环:嵌套循环生成 O(n)强>过程。这需要一段时间。你需要更高效的东西,至少 O (n log(n))。
Project Euler的目的之一是让我们研究更有效的算法。对于这个,您可能想要使用divisor function,这将需要众多素数生成函数中的任何一个。
你应该开发一套技巧&#34;您import
解决大多数问题的模块。事实上,你应该已经有一个从早期问题中产生素数的假设(假设你以某种顺序攻击它们)。如果没有,请尝试this one。
答案 1 :(得分:1)
我同意@ Prune的回答,但这是你的强力算法的更快版本:
import numpy as np
i = 1
f = lambda N: (N * (N + 1)) // 2
ndmax = 0
while True:
t = f(i)
p = np.arange(1, t + 1)
r = np.mod(t, p)
nd = p.size - np.count_nonzero(r) + 1
if nd > ndmax: # track progress
ndmax = nd
print((i, t, nd))
if nd > 500:
print ("ANSWER: " , t)
break
i += 1
divisor_count
)from sympy import divisor_count
import numpy as np
i = 1
f = lambda N: (N * (N + 1)) // 2
ndmax = 0
while True:
t = f(i)
nd = divisor_count(t)
if nd > ndmax: # track progress
ndmax = nd
print((i, t, nd))
if nd > 500:
print ("ANSWER: " , t)
break
i += 1
有关详情,请参阅divisor_count
及其中的参考资料。