Project Euler#12的python解决方案有什么问题?

时间:2012-02-07 19:21:27

标签: python algorithm math

可能的扰流板警告

我花了很多年时间试图改进这个算法并弄清楚出了什么问题,但我似乎无法弄清楚为什么输出的答案是错误的。

我正在尝试解决Project Euler #12,以获得最低三角数以超过500个除数,但它说我的答案是错误的。

这是我的Python代码:

import time

# function to get the number of divisors
def div(n):
    d=2
    for i in range(2,int(n**.5)+2):
        if (n % i) == 0:
            d += 1
    return d

start = time.time()

w = True
n=m=1
while w:
    n += 1
    s = (n*(n+1))/2 # nth triangle number
    r = div(s)
    if r > m:
        m = r
        print s,"has",r,"divisors"
        if r > 500:
            w = False

print "Solved in",((time.time()-start)*1000),"milliseconds"

该代码的输出为此(66秒内):

3 has 2 divisors
6 has 4 divisors
36 has 6 divisors
120 has 9 divisors

...

76576500 has 289 divisors
103672800 has 325 divisors
236215980 has 385 divisors
842161320 has 513 divisors
Solved in 65505.5799484 milliseconds

但是,如果我在Project Euler问题中输入842161320,则说它不正确。

我做错了什么?

3 个答案:

答案 0 :(得分:5)

我看到两个错误:

  • 您的div功能已损坏:div(24) == 5,而应该是8
  • 您的第一个三角形数字为3,但应为1

您可以像这样实施div

import math
def divisors(n):
  return sum(1 for x in range(1, n+1) if n % x == 0)

此外,该代码效率低下,一些改善它的建议是:

不使用公式计算n三角形数字,而是使用滚动总和:

import itertools

s = 0
for i in itertools.count(1):
  s += i
  if div(s) > 500:
    print s
    break

另外,使用prime factors to calculate the number of divisors。您可以创建一个素数因子缓存以获得最佳性能。

答案 1 :(得分:2)

你在计算除数的总数。例如,36有9个除数:1,2,3,4,6,9,12,18,36。确实,算法只需要测试小于sqrt(n)的数字来查找所有除数,但是你仍然需要在计数中包含隐含的“大”除数。

答案 2 :(得分:0)

解决

在Niklas的帮助下,改变我的div方法,我得到了答案。此外,它现在只占我之前算法的8%。

现在算法如下:

import time
import itertools

def div(n):
    d=0
    for i in range(1,int(n**.5)+1):
        if (n % i) == 0:
            d += 1
    return 2*d

start = time.time()

s = m = 0
for i in itertools.count(1):
    s += i
    r = div(s)
    if r > m:
        m = r
        print s,"has",r,"factors"
        if div(s) > 500:
            break

print "Solved in",((time.time()-start)*1000),"milliseconds"