简体   繁体   中英

How can I optimize my code to print amicable numbers?

I have tried this following code and it takes a lot of time when I set lower = 0 and upper = 10000

def sumPdivisors(n):
  '''This function returns the sum of proper divisors of a number'''
  lst = []
  for i in range(1,n//2+1):
    if n%i == 0:
      lst.append(i)
  return(sum(lst))

lower = int(input("Enter the lower value of range: "))
upper = int(input("Enter the upper value of range: "))

lst = []

for i in range(lower, upper+1):
    if i == 0:
      continue
    else:
      for j in range(i, upper):
        if i!=j and sumPdivisors(i) == j and sumPdivisors(j) == i:
          lst.append((i,j))
          break

print(lst)

There are two things that you could do here.

Memoization

There's already a great explanation of what memoization is elsewhere on this site [link] , but here's how it's relevant to your problem:

  • sumPdivisors is called very frequently in the for-loop at the bottom of your code snippet. For really large inputs n , it will take a long time to run.

  • sumPdivisors is called with the same input n multiple times.

  • You can speed things up by saving the result of calling sumPdivisors on different inputs somehow, like in a dictionary that maps integers to the resulting output when you call sumPdivisors with that corresponding integer. This is kind of what memoization is. You're precomputing the possible outputs of sumPdivisors and storing them for later. Read the link for a more in-depth explanation.

Don't add the numbers in sumPdivisors to a list

You can just add these numbers as you iterate instead of appending them to a list, then summing them. This change won't have as great of an impact as adding memoization to your code.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM