-6

I have written this code for solving Euler Project No 12, but my code runs slow.

How can I make it running faster? I have read some suggests about finding divisors, but I do not understand the logic of using sqrt for n.

Can you explain the logic of it?

Here's my code:

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:])
thewaywewere
  • 8,128
  • 11
  • 41
  • 46
Perviz Mamedov
  • 121
  • 1
  • 5

2 Answers2

0

a and b are divisors of n if a * b = n. You can, without loss of generality, set b >= a. Therefore a * a is the upper limit; i.e. you only need to consider up to and including the square root of n. Once you have an a, you can trivially infer b.

You can set the upper limit to be d * d <= n rather than d <= sqrt(n) so obviating any computation of a square root. That will be marginally faster still.

Bathsheba
  • 231,907
  • 34
  • 361
  • 483
0

You just want to know the number of divisors:

For any number N there are always an even number of divisors as every dividor x requires to be multiplied by another y that is itself a divisor of N except if x=sqrt(N) yileds an integer result as that would mean that x*x=N and that would be an only number. So every divisor is grouped in pairs except for sqrt(N) if it results to be a divisor.

Then you first check if the root is a divisor and then just calculate until it and add two to the count each time as the rest will always be pairs:

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
Adirio
  • 5,040
  • 1
  • 14
  • 26