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, |
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 /* [↓] |
a=1 /* [↓] use all or only odd #s. ___ */ |
||
do j=2+odd by 1+odd while j*j<x /*divide by |
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 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: <tt> 0 10 1 20000 166320 1441440 11796480000 </tt> |
'''output''' when using the following input: <tt> 0 10 1 20000 166320 1441440 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 |
This REXX version is about 10% faster than the REXX version 2 (especially when specifying larger numbers). |
||
It accomplishes a faster speed by incorporating the |
It accomplishes a faster speed by incorporating the calculation of an ''integer square root'' of an integer (without using any floating point arithmetic). |
||
<br>''integer square root'' of an integer (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, |
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 '' |
|||
⚫ | |||
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 */ |
|||
/*────────────────────────────────────────────────────────────────────────────*/ |
|||
do while q>1; q=q%4; _=z-r-q; r=r%2; if _>=0 then do; z=_; r=r+q; end; end |
|||
a=1 /* [↓] use all or only odd #s. ___ */ |
|||
⚫ | |||
iqx=iSqrt(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 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''' is identical to the 2<sup>nd</sup> REXX version. <br><br> |
'''output''' is identical to the 2<sup>nd</sup> REXX version. <br><br> |