Proper divisors: Difference between revisions

Content added Content deleted
m (→‎version 2: added/changed whitespace and comments, changed output alignment and indentation.)
Line 1,431: Line 1,431:


===version 2===
===version 2===
The following REXX version is an adaptation of the ''optimized'' version for the REXX language example for ''Factors of an integer''.
The following REXX version is an adaptation of the   ''optimized''   version for the REXX language example for   ''Factors of an integer''.


This REXX version handles all integers   (negative, zero, positive)   and automatically adjusts the precision (digits).
This REXX version handles all integers   (negative, zero, positive)   and automatically adjusts the precision (digits).
Line 1,437: Line 1,437:


With the (subroutine) optimization, it's over twenty times faster.
With the (subroutine) optimization, it's over twenty times faster.
<lang rexx>/*REXX program finds proper divisors (& count) of integer ranges; max of #s. */
<lang rexx>/*REXX program finds proper divisors (& count) of integer ranges; & max count.*/
parse arg bot top inc range xtra /*get optional args from C.L. */
parse arg bot top inc range xtra /*get optional arguments from CL.*/
top=word(top bot 10,1); bot=word(bot 1,1); inc=word(inc 1,1) /*1st range*/
top=word(top bot 10,1); bot=word(bot 1,1); inc=word(inc 1,1) /*1st range.*/
if range=='' then range=top /*use TOP for the 2nd range.*/
if range=='' then range=top /*use TOP for the 2nd range. */
w=length(top)+1; numeric digits max(9,w) /*'nuff digs for // operation*/
w=length(top)+1; numeric digits max(9,w) /*'nuff digits for // operation*/
m=0
m=0
do n=bot to top by inc; q=Pdivs(n); #=words(q); if q=='∞' then #=q
do n=bot to top by inc; q=Pdivs(n); #=words(q); if q=='∞' then #=q
say right(n,digits()) 'has' center(#,4) "proper divisors: " q
say right(n,max(20,digits())) 'has' center(#,4) "proper divisors: " q
end /*n*/ /* [↑] process a range of integers. */
end /*n*/ /* [↑] process 1st range of integers.*/
say; @.='and'
say; @.='and'
do r=1 for range; q=Pdivs(r); #=words(q); if #<m then iterate
do r=1 for range; q=Pdivs(r); #=words(q); if #<m then iterate
@.#=@.# @. r; m=#
@.#=@.# @. r; m=#
end /*r*/ /* [↑] process a range of integers. */
end /*r*/ /* [↑] process 2nd range of integers.*/
__='is the highest number of proper divisors in range 1──►'range

say m 'is the highest number of proper divisors in range 1──►'range", and it's for: " subword(@.m,3)
say m __", and it's for: " subword(@.m,3)
say /* [↓] handle any given extra numbers. */
say /* [↓] handle any given extra numbers.*/
do i=1 for words(xtra); n=word(xtra,i)
do i=1 for words(xtra); n=word(xtra,i)
numeric digits max(9,length(n)+1); q=Pdivs(n); #=words(q)
numeric digits max(9,length(n)+1); q=Pdivs(n); #=words(q)
say right(n,digits()) 'has' center(#,4) "proper divisors."
say right(n,max(20,digits())) 'has' center(#,4) "proper divisors."
end /*i*/ /* [↑] support extra given integers. */
end /*i*/ /* [↑] support extra specified integers*/
exit /*stick a fork in it, we're all done. */
exit /*stick a fork in it, we're all done. */
/*────────────────────────────────────────────────────────────────────────────*/
/*──────────────────────────────────PDIVS subroutine──────────────────────────*/
Pdivs: procedure; parse arg x,b; x=abs(x); if x==1 then return ''
Pdivs: procedure; parse arg x,b; x=abs(x); if x==1 then return ''
odd=x//2; if x==0 then return '∞'
odd=x//2; if x==0 then return '∞'
a=1 /* [↓] process only EVEN│ODD integers.*/
a=1 /* [↓] do only EVEN or ODD #s. ___*/
do j=2+odd by 1+odd while j*j<x /*divide by all integers up to √x. */
do j=2+odd by 1+odd while j*j<x /*divide by all the integers up to x */
if x//j==0 then do; a=a j; b=x%j b; end /*add divisors to α&ß lists if ÷*/
if x//j==0 then do; a=a j; b=x%j b; end /*if ÷, add both divisors to α&ß*/
end /*j*/ /* [↑] % is the REXX integer division*/
end /*j*/ /* [↑] % is the REXX integer division*/
/* [↓] adjust for square. _ */
/* [↓] adjust for a square. ___*/
if j*j==x then return a j b /*Was X a square? If so, add √x. */
if j*j==x then return a j b /*Was X a square? If so, add √ x */
return a b /*return the divisors (both lists). */</lang>
return a b /*return the divisors (both lists). */</lang>
'''output''' when using the following input: &nbsp; <tt> 0 &nbsp; 10 &nbsp; 1 &nbsp; &nbsp; &nbsp; 20000 &nbsp; &nbsp; &nbsp; 166320 &nbsp; 1441440 &nbsp; 11796480000 </tt>
'''output''' when using the following input: &nbsp; <tt> 0 &nbsp; 10 &nbsp; 1 &nbsp; &nbsp; &nbsp; 20000 &nbsp; &nbsp; &nbsp; 166320 &nbsp; 1441440 &nbsp; 11796480000 </tt>
<pre>
<pre>
0 has ∞ proper divisors: ∞
0 has ∞ proper divisors: ∞
1 has 0 proper divisors:
1 has 0 proper divisors:
2 has 1 proper divisors: 1
2 has 1 proper divisors: 1
3 has 1 proper divisors: 1
3 has 1 proper divisors: 1
4 has 2 proper divisors: 1 2
4 has 2 proper divisors: 1 2
5 has 1 proper divisors: 1
5 has 1 proper divisors: 1
6 has 3 proper divisors: 1 2 3
6 has 3 proper divisors: 1 2 3
7 has 1 proper divisors: 1
7 has 1 proper divisors: 1
8 has 3 proper divisors: 1 2 4
8 has 3 proper divisors: 1 2 4
9 has 2 proper divisors: 1 3
9 has 2 proper divisors: 1 3
10 has 3 proper divisors: 1 2 5
10 has 3 proper divisors: 1 2 5


79 is the highest number of proper divisors in range 1──►20000, and it's for: 15120 and 18480
39 is the highest number of proper divisors in range 1──►2000, and it's for: 1680


166320 has 159 proper divisors.
166320 has 159 proper divisors.
1441440 has 287 proper divisors.
1441440 has 287 proper divisors.
11796480000 has 329 proper divisors.
11796480000 has 329 proper divisors.
</pre>
</pre>