如何让此代码更快?

问题描述:

我已经编写了解决Euler Project No 12的代码,但是我的代码运行缓慢。如何让此代码更快?

如何让它运行得更快?我已阅读了一些有关寻找除数的建议,但我不明白使用sqrt代替n的逻辑。

你能解释一下它的逻辑吗?

这里是我的代码:如果a * b = nn

def sumdiv(n): 
    l=[d for d in range(1,int(n/2)+1) if n%d==0] # used n/2 to short loop 
    return len(l)+1 # added n itself 
trnums=[1,3] 

while sumdiv(trnums[-1])<=501: 
    k=trnums[-1]-trnums[-2]+1 
    trnums.append(trnums[-1]+k) 
print(trnums[-2:]) 
+1

使用'[d在范围d (1,int(math.sqrt(n))+ 1)if n%d == 0]',你在这点之后没有找到任何除数。这将_will_让你的代码更快。 –

+0

我已经知道这种方法,但我需要逻辑使用sqrt –

+2

是你的问题“为什么我应该停在'int(math.sqrt(n))+ 1'? – Adirio

ab是除数。您可以在不失一般性的情况下设置b >= a。因此a * a是上限;即您只需考虑并包括n的平方根。一旦你有一个a,你可以平凡地推断b

您可以设置上限为d * d <= n,而不是d <= sqrt(n)所以避免平方根的任何计算。这仍然会稍微快一点。

+0

lest take f或示例28. –

+0

28的除数是1,2,4,7,14,28。我改变了我的代码。但是asnwer是错的 –

+0

n = 28 (i,范围(1,int(n ** 0.5)+1): 如果n%i == 0: print(i) –

你只是想知道除数的数量:总有偶数个约数,因为每个dividor x

对于任何数量N需要由另一y这本身就是除如果N除数相乘x=sqrt(N)指定了一个整数结果,因为这意味着x*x=N并且这将是唯一的数字。因此,除了sqrt(N),如果结果是除数,则每个除数都会成对分组。

那你第一次检查,如果根是一个除数,然后只计算,直到它并添加两到计数每次为其余的将永远是对的:

def number_of_divisors(n): 
    root = math.sqrt(n) 
    if root == int(root): 
     number = 1 
     limit = int(root) 
    else: 
     number = 0 
     limit = int(root) + 1 
    for i in range(1, limit): 
     if (n % i) == 0: 
      number += 2 
    return number 

i = 1 
s = 1 
while number_of_divisors(s) < 501: 
    i += 1 
    s += i 

print(i) # 12375 
print(s) # 76576500 
print(number_of_divisors(s)) # 576