Proper divisors: Difference between revisions

Content added Content deleted
m (→‎version 2: updated the output to reflect the highest number of Pdivs for 20k instead of 2k.)
(→‎{{header|REXX}}: added/changed whitespace and comments, moved the iSqrt function in-line, changed wording in the REXX section header.)
Line 1,644: Line 1,644:
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,max(20,digits())) 'has' center(#,4) "proper divisors."
say right(n,max(20,w)) 'has' center(#,4) "proper divisors."
end /*i*/ /* [↑] support extra specified 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: 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 /* [↓] do only EVEN or ODD #s. ___*/
a=1 /* [↓] use all or only odd #s. ___ */
do j=2+odd by 1+odd while j*j<x /*divide by all the integers up to √ x */
do j=2+odd by 1+odd while j*j<x /*divide by some integers up to X */
if x//j==0 then do; a=a j; b=x%j b; end /*if ÷, add both divisors to α&ß*/
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 a 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''' &nbsp; 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: ∞
Line 1,679: Line 1,679:


===version 3===
===version 3===
This REXX version is slightly faster than the REXX version 2 &nbsp; (especially when specifying larger numbers).
This REXX version is about 10% faster than the REXX version 2 &nbsp; (especially when specifying larger numbers).


It accomplishes a faster speed by incorporating the use of the &nbsp; '''iSqrt''' &nbsp; function which computes the &nbsp;
It accomplishes a faster speed by incorporating the calculation of an &nbsp; ''integer square root'' &nbsp; of an integer &nbsp; (without using any floating point arithmetic).
<br>''integer square root'' &nbsp; of an integer &nbsp; (without using any floating point arithmetic).
<lang rexx>/*REXX program finds proper divisors (& count) of integer ranges; & max count.*/
<lang rexx>/*REXX program finds proper divisors (& count) of integer ranges; & max count.*/
parse arg bot top inc range xtra /*get optional arguments from CL.*/
parse arg bot top inc range xtra /*get optional arguments from CL.*/
Line 1,701: Line 1,700:
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,max(20,digits())) 'has' center(#,4) "proper divisors."
say right(n,max(20,w)) 'has' center(#,4) "proper divisors."
end /*i*/ /* [↑] support extra specified 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. */
/*────────────────────────────────────────────────────────────────────────────*/
/*────────────────────────────────────────────────────────────────────────────*/
iSqrt: procedure; parse arg x; r=0; q=1; do while q<=x; q=q*4; end
Pdivs: procedure; parse arg x,b; x=abs(x); if x==1 then return ''
odd=x//2; if x==0 then return '∞' /* ___ */
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
z=x; r=0; q=1; do while q<=z; q=q*4; end /*R will be the integer √ X */
/*────────────────────────────────────────────────────────────────────────────*/
Pdivs: procedure; parse arg x,b; x=abs(x); if x==1 then return ''
do while q>1; q=q%4; _=z-r-q; r=r%2; if _>=0 then do; z=_; r=r+q; end; end
odd=x//2; if x==0 then return '∞'
a=1 /* [↓] use all or only odd #s. ___ */
do j=2+odd by 1+odd while j<r /*divide by some integers up to X */
iqx=iSqrt(x)
a=1 /* [↓] do only EVEN or ODD #s. ___*/
do j=2+odd by 1+odd while j<iqx /*divide by all the integers up to √ x */
if x//j==0 then do; a=a j; b=x%j b; end /*if ÷, add both divisors to α&ß*/
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 a 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''' &nbsp; is identical to the 2<sup>nd</sup> REXX version. <br><br>
'''output''' &nbsp; is identical to the 2<sup>nd</sup> REXX version. <br><br>