Product of divisors

From Rosetta Code
Product of divisors is a draft programming task. It is not yet considered ready to be promoted as a complete task, for reasons that should be found in its talk page.

Given a positive integer, return the product of its positive divisors.

Task

Show the result for the first 50 positive integers.



Python

Finding divisors efficiently

<lang Python>def product_of_divisors(n):

   assert(isinstance(n, int) and 0 < n)
   ans = i = j = 1
   while i*i <= n:
       if 0 == n%i:
           ans *= i
           j = n//i
           if j != i:
               ans *= j
       i += 1
   return ans
   

if __name__ == "__main__":

   print([product_of_divisors(n) for n in range(1,51)])</lang>
Output:
[1, 2, 3, 8, 5, 36, 7, 64, 27, 100, 11, 1728, 13, 196, 225, 1024, 17, 5832, 19, 8000, 441, 484, 23, 331776, 125, 676, 729, 21952, 29, 810000, 31, 32768, 1089, 1156, 1225, 10077696, 37, 1444, 1521, 2560000, 41, 3111696, 43, 85184, 91125, 2116, 47, 254803968, 343, 125000]

Choosing the right abstraction

This is really an exercise in defining a divisors function, and the only difference between the suggested Sum and Product draft tasks boils down to two trivial morphemes:

reduce(add, divisors(n), 0) vs reduce(mul, divisors(n), 1)

The goal of Rosetta code (see the landing page) is to provide contrastive insight (rather than comprehensive coverage of homework questions :-). Perhaps the scope for contrastive insight in the matter of divisors is already exhausted by the trivially different Proper divisors task.

<lang python>Sums and products of divisors

from math import floor, sqrt from functools import reduce from operator import add, mul


  1. divisors :: Int -> [Int]

def divisors(n):

   List of all divisors of n including n itself.
   
   root = floor(sqrt(n))
   lows = [x for x in range(1, 1 + root) if 0 == n % x]
   return lows + [n // x for x in reversed(lows)][
       (1 if n == (root * root) else 0):
   ]


  1. ------------------------- TEST -------------------------
  2. main :: IO ()

def main():

   Product and sums of divisors for each integer in range [1..50]
   
   print('Products of divisors:')
   for n in range(1, 1 + 50):
       print(n, '->', reduce(mul, divisors(n), 1))
   print('Sums of divisors:')
   for n in range(1, 1 + 100):
       print(n, '->', reduce(add, divisors(n), 0))


  1. MAIN ---

if __name__ == '__main__':

   main()</lang>