Product of divisors: Difference between revisions
m (→{{header|REXX}}: added a REXX stub.) |
(→{{header|REXX}}: added the computer programming language REXX.) |
||
Line 73: | Line 73: | ||
=={{header|REXX}}== |
=={{header|REXX}}== |
||
<lang rexx>/*REXX program displays the first N product of divisors (shown in a columnar format).*/ |
|||
numeric digits 20 /*ensure enough decimal digit precision*/ |
|||
parse arg n . /*obtain optional argument from the CL.*/ |
|||
if n=='' | n=="," then n= 50 /*Not specified? Then use the default.*/ |
|||
say 'the sums of divisors for ' n " integers:"; say /*show what output is being shown*/ |
|||
say '─index─' center("sum of divisors", 101,'─') /*display a title for the tau numbers. */ |
|||
w= max(7, length(n) ) /*W: used to align 1st output column. */ |
|||
$= /*$: the output list, shown ten/line. */ |
|||
do j=1 for N /*process N positive integers. */ |
|||
$= $ || right( commas(sigma(j)), 20) /*add a sigma (sum) to the output list.*/ |
|||
if j//5\==0 then iterate /*Not a multiple of 10? Don't display.*/ |
|||
say center(commas(j-4), 7)' ' $ /*display partial list to the terminal.*/ |
|||
$= /*start with a blank line for next line*/ |
|||
end /*j*/ |
|||
if j<=5 then j= 2 /handle case if this is the 1st display*/ |
|||
if $\=='' then say center((j-1), 7)' ' $ /*any residuals sums left to display? */ |
|||
exit 0 /*stick a fork in it, we're all done. */ |
|||
/*──────────────────────────────────────────────────────────────────────────────────────*/ |
|||
commas: parse arg ?; do jc=length(?)-3 to 1 by -3; ?=insert(',', ?, jc); end; return ? |
|||
/*──────────────────────────────────────────────────────────────────────────────────────*/ |
|||
iSqrt: procedure; parse arg x; q= 1; r= 0; do while q<=x; q= q*4; end |
|||
do while q>1; q=q%4; _=x-r-q; r=r%2; if _>=0 then do;x=_;r=r+q; end; end; return r |
|||
/*──────────────────────────────────────────────────────────────────────────────────────*/ |
|||
sigma: procedure; parse arg x; if x==1 then return 1; odd=x // 2 /* // ◄──remainder.*/ |
|||
p= x /* [↓] only use EVEN or ODD integers.*/ |
|||
do k=2+odd by 1+odd while k*k<x /*divide by all integers up to √x. */ |
|||
if x//k==0 then p= p * k * (x % k) /*multiple the two divisors to product.*/ |
|||
end /*k*/ /* [↑] % is the REXX integer division*/ |
|||
if k*k==x then return p * k /*Was X a square? If so, add √ x */ |
|||
return p /*return (sigma) sum of the divisors. */</lang> |
|||
{{out|output|text= when using the default input:}} |
|||
<pre> |
|||
the sums of divisors for 50 integers: |
|||
─index─ ───────────────────────────────────────────sum of divisors─────────────────────────────────────────── |
|||
1 1 2 3 8 5 |
|||
6 36 7 64 27 100 |
|||
11 11 1,728 13 196 225 |
|||
16 1,024 17 5,832 19 8,000 |
|||
21 441 484 23 331,776 125 |
|||
26 676 729 21,952 29 810,000 |
|||
31 31 32,768 1,089 1,156 1,225 |
|||
36 10,077,696 37 1,444 1,521 2,560,000 |
|||
41 41 3,111,696 43 85,184 91,125 |
|||
46 2,116 47 254,803,968 343 125,000 |
|||
</pre> |
|||
=={{header|Wren}}== |
=={{header|Wren}}== |
Revision as of 19:05, 20 December 2020
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
- 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): ]
- ------------------------- TEST -------------------------
- 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))
- MAIN ---
if __name__ == '__main__':
main()</lang>
REXX
<lang rexx>/*REXX program displays the first N product of divisors (shown in a columnar format).*/ numeric digits 20 /*ensure enough decimal digit precision*/ parse arg n . /*obtain optional argument from the CL.*/ if n== | n=="," then n= 50 /*Not specified? Then use the default.*/ say 'the sums of divisors for ' n " integers:"; say /*show what output is being shown*/ say '─index─' center("sum of divisors", 101,'─') /*display a title for the tau numbers. */ w= max(7, length(n) ) /*W: used to align 1st output column. */ $= /*$: the output list, shown ten/line. */
do j=1 for N /*process N positive integers. */ $= $ || right( commas(sigma(j)), 20) /*add a sigma (sum) to the output list.*/ if j//5\==0 then iterate /*Not a multiple of 10? Don't display.*/ say center(commas(j-4), 7)' ' $ /*display partial list to the terminal.*/ $= /*start with a blank line for next line*/ end /*j*/
if j<=5 then j= 2 /handle case if this is the 1st display*/ if $\== then say center((j-1), 7)' ' $ /*any residuals sums left to display? */ exit 0 /*stick a fork in it, we're all done. */ /*──────────────────────────────────────────────────────────────────────────────────────*/ commas: parse arg ?; do jc=length(?)-3 to 1 by -3; ?=insert(',', ?, jc); end; return ? /*──────────────────────────────────────────────────────────────────────────────────────*/ iSqrt: procedure; parse arg x; q= 1; r= 0; do while q<=x; q= q*4; end
do while q>1; q=q%4; _=x-r-q; r=r%2; if _>=0 then do;x=_;r=r+q; end; end; return r
/*──────────────────────────────────────────────────────────────────────────────────────*/ sigma: procedure; parse arg x; if x==1 then return 1; odd=x // 2 /* // ◄──remainder.*/
p= x /* [↓] only use EVEN or ODD integers.*/ do k=2+odd by 1+odd while k*k<x /*divide by all integers up to √x. */ if x//k==0 then p= p * k * (x % k) /*multiple the two divisors to product.*/ end /*k*/ /* [↑] % is the REXX integer division*/ if k*k==x then return p * k /*Was X a square? If so, add √ x */ return p /*return (sigma) sum of the divisors. */</lang>
- output when using the default input:
the sums of divisors for 50 integers: ─index─ ───────────────────────────────────────────sum of divisors─────────────────────────────────────────── 1 1 2 3 8 5 6 36 7 64 27 100 11 11 1,728 13 196 225 16 1,024 17 5,832 19 8,000 21 441 484 23 331,776 125 26 676 729 21,952 29 810,000 31 31 32,768 1,089 1,156 1,225 36 10,077,696 37 1,444 1,521 2,560,000 41 41 3,111,696 43 85,184 91,125 46 2,116 47 254,803,968 343 125,000
Wren
<lang ecmascript>import "/math" for Int, Nums import "/fmt" for Fmt
System.print("The products of positive divisors for the first 50 positive integers are:") for (i in 1..50) {
Fmt.write("$9d ", Nums.prod(Int.divisors(i))) if (i % 5 == 0) System.print()
}</lang>
- Output:
The products of positive divisors for the first 50 positive integers are: 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