The most optimized way to find the sum of divisors of a number for numbers in a given range in python

Question:

I would like to find the sum of divisors of a number for numbers in a given range in the fastest possible way.

My current one looks like this

import math


def divSum(num):
    result = 0

    for i in range(2, int(math.sqrt(num)+1)):
        if num % i == 0:
            if i == (num / i):
                result = result + i
            else:
                result = result + (i + num / i)
    return int(result + 1)


list_of_number = [*range(0, 1000000, 1)]

print(list(map(divSum, list_of_number)))

At 100,000, the problems begin. Is there any way to optimize or the current one is fine overall. Thank you

Asked By: Tylzan

||

Answers:

In your particular case I would say the fastest you can get is the Sieve of Eratosthenes.
This way we avoid work duplication.
Keep in mind that this approach is good as long as you need the result for all numbers between 0 and 1e6.
This might not be the best idea to compute the sum for a particular number.

# Set how many numbers we are testing
MAX = 1_000_000
# Initialize a list to avoid memory reallocation
# Set 1 as initial value as all numbers are divisible by 1
SUMS = [1 for _ in range(MAX + 1)]
# Take every number and add it to all its multiples not grater than MAX
# No number not grater than MAX will have a divisor higher than MAX / 2
for i in range(2, (MAX + 1) // 2):
    # Don't start at i to avoid adding i to its own sum
    for index in range(i * 2, MAX + 1, i):
        # i is a divisor of index
        SUMS[index] += i

In my machine this code took 1.5 seconds.

Once we have the list SUMS, we can get the result of your function in constant time.
For all i from 0 to MAX, SUMS[i] returns the same as divSum(i).

Answered By: Jorge Luis
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.