Efficient python code for printing product number dividers

I am trying to solve the problem of printing the product of all divisors of a given number. The number of test cases is the number 1 <= t <= 300000, and the number itself can be in the range from 1 <= n <= 500000

I wrote the following code, but it always exceeds 2 seconds. Is there a way to speed up the code?

from math import sqrt

def divisorsProduct(n):
    ProductOfDivisors=1

    for i in range(2,int(round(sqrt(n)))+1):
        if n%i==0: 
            ProductOfDivisors*=i

            if n/i != i:
                ProductOfDivisors*=(n/i)    

    if ProductOfDivisors <= 9999:
        print ProductOfDivisors
    else:
        result = str(ProductOfDivisors)
        print result[len(result)-4:] 

T = int(raw_input())

for i in range(1,T+1):
    num = int(raw_input())
    divisorsProduct(num)

Thanks.

+3
source share
3 answers

, " ". , , - . . , , , , , , .

, , 72 2 * 3 = 6, - . , . , .

, , , . , ​​. , .

, , n - 1 n, 2 n/2 .. - , n - , - , - .

, n ( , n ).

, , . , 2, n, 3 .. , 2s, 3s ..

, , , , , . , p * p <= m, p <= sqrt (m)

, . , , 2 ^ * 3 ^ j * 7 ^ k. , , n, 0, (i + 1) (j + 1) (k + 1).

, 72 = 2 ^ 3 * 3 ^ 2, 4 * 3 = 12, 72 ^ 6 = 139,314,069,504.

, , O (n). - n .

+6

if , , , .

, . , , , . , , , ? I.e., 2 3, 6.

, , .

C , .

+1

, , . product_of_divisors (500000).

import math

def number_of_divisors(maxval=500001):
    """ Example: the number of divisors of 12 is 6:  1, 2, 3, 4, 6, 12.
        Given a prime factoring of n, the number of divisors of n is the
        product of each factor multiplicity plus one (mpo in my variables).

        This function works like the Sieve of Eratosthenes, but marks each
        composite n with the multiplicity (plus one) of each prime factor. """
    numdivs = [1] * maxval   # multiplicative identity
    currmpo = [0] * maxval

    # standard logic for 2 < p < sqrt(maxval)
    for p in range(2, int(math.sqrt(maxval))):
        if numdivs[p] == 1:   # if p is prime
            for exp in range(2,50): # assume maxval < 2^50
                pexp = p ** exp
                if pexp > maxval:
                    break
                exppo = exp + 1
                for comp in range(pexp, maxval, pexp):
                    currmpo[comp] = exppo
            for comp in range(p, maxval, p):
                thismpo = currmpo[comp] or 2
                numdivs[comp] *= thismpo
                currmpo[comp] = 0  # reset currmpo array in place

    # abbreviated logic for p > sqrt(maxval)
    for p in range(int(math.sqrt(maxval)), maxval):
        if numdivs[p] == 1:   # if p is prime
            for comp in range(p, maxval, p):
                numdivs[comp] *= 2

    return numdivs

# this initialization times at 7s on my machine
NUMDIV = number_of_divisors()

def product_of_divisors(n):
    if NUMDIV[n] % 2 == 0:
        # each pair of divisors has product equal to n, for example
        # 1*12 * 2*6 * 3*4  =  12**3
        return n ** (NUMDIV[n] / 2)
    else:
        # perfect squares have their square root as an unmatched divisor
        return n ** (NUMDIV[n] / 2) * int(math.sqrt(n))

# this loop times at 13s on my machine
for n in range(500000):
    a = product_of_divisors(n)

7s , 13s . , , C. (@someone : ?)

+1

Source: https://habr.com/ru/post/1709632/


All Articles