Abundant, deficient and perfect number classifications: Difference between revisions

Content added Content deleted
m (→‎{{header|REXX}}: added/changed whitespace and comments, added optimization.)
Line 1,162: Line 1,162:
=={{header|REXX}}==
=={{header|REXX}}==
===version 1===
===version 1===
<lang rexx>/*REXX pgm counts the # of abundant/deficient/perfect numbers in a range*/
<lang rexx>/*REXX pgm counts the number of abundant/deficient/perfect numbers in a range.*/
parse arg low high . /*get optional arguments*/
parse arg low high . /*get optional args from C.L. */
high=word(high low 20000,1); low=word(low 1,1) /*get the LOW and HIGH. */
high=word(high low 20000,1); low=word(low 1,1) /*get the LOW and HIGH values.*/
say center('integers from ' low " to " high, 45, "═")
say center('integers from ' low " to " high, 45, "═")
a=0; d=0; p=0 /*set all types of sums to bupkis*/
!.=0 /*define all types of sums to zero. */
do j=low to high; $=sigma(j) /*find the sigma for an integer range. */

do j=low to high; $=sigma(j) /*find the sigma for an int range*/
if $<j then !.d=!.d+1 /*it's a deficient number.*/
if $<j then d=d+1 /*it's a deficient number. */
else if $>j then !.a=!.a+1 /* " " abundant " */
else if $>j then a=a+1 /* " " abundant " */
else !.p=!.p+1 /* " " perfect " */
end /*j*/
else p=p+1 /* " " perfect " */
end /*j*/


say ' the number of perfect numbers: ' right(p, length(high))
say ' the number of perfect numbers: ' right(!.p, length(high))
say ' the number of abundant numbers: ' right(a, length(high))
say ' the number of abundant numbers: ' right(!.a, length(high))
say ' the number of deficient numbers: ' right(d, length(high))
say ' the number of deficient numbers: ' right(!.d, length(high))
exit /*stick a fork in it, we're done.*/
exit /*stick a fork in it, we're all done. */
/*────────────────────────────────────────────────────────────────────────────*/
/*──────────────────────────────────SIGMA subroutine────────────────────*/
sigma: procedure; parse arg x; if x<2 then return 0; odd=x//2
sigma: procedure; parse arg x; if x<2 then return 0; odd=x//2 /*odd? */
s=1 /* [↓] use only EVEN|ODD integers*/
s=1 /* [↓] only use EVEN or ODD integers.*/
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 integers up to √x. */
if x//j==0 then s=s+j+ x%j /*add the two divisors to the sum*/
if x//j==0 then s=s+j+ x%j /*add the two divisors to (sigma) sum. */
end /*j*/ /* [↑] % is REXX integer divide*/
end /*j*/ /* [↑] % is the REXX integer division*/
/* [↓] adjust for square. _ */
/* [↓] adjust for a square. ___ */
if j*j==x then s=s+j /*Was X a square? If so, add √x.*/
if j*j==x then s=s+j /*Was X a square? If so, add √ x */
return s /*return the sum of the divisors.*/</lang>
return s /*return (sigma) sum of the divisors. */</lang>
'''output''' &nbsp; when using the default inputs:
'''output''' &nbsp; when using the default inputs:
<pre>
<pre>
Line 1,197: Line 1,196:
===version 1.5===
===version 1.5===
This version is pretty much the same as the 1<sup>st</sup> version but uses an &nbsp; ''integer square root'' &nbsp; function to calculate the limit of the &nbsp; '''do''' &nbsp; loop in the &nbsp; '''sigma''' &nbsp; function.
This version is pretty much the same as the 1<sup>st</sup> version but uses an &nbsp; ''integer square root'' &nbsp; function to calculate the limit of the &nbsp; '''do''' &nbsp; loop in the &nbsp; '''sigma''' &nbsp; function.
<lang rexx>/*REXX pgm counts the # of abundant/deficient/perfect numbers in a range*/
<lang rexx>/*REXX pgm counts the number of abundant/deficient/perfect numbers in a range.*/
parse arg low high . /*get optional arguments*/
parse arg low high . /*get optional args from C.L. */
high=word(high low 20000,1); low=word(low 1,1) /*get the LOW and HIGH. */
high=word(high low 20000,1); low=word(low 1,1) /*get the LOW and HIGH values.*/
say center('integers from ' low " to " high, 45, "═")
say center('integers from ' low " to " high, 45, "═")
!.=0 /*set all types of sums to zero. */
!.=0 /*define all types of sums to zero. */
do j=low to high; $=sigma(j) /*find the sigma for an int range*/
do j=low to high; $=sigma(j) /*find the sigma for an integer range. */
if $<j then !.d=!.d+1 /*it's a deficient number*/
if $<j then !.d=!.d+1 /*it's a deficient number.*/
else if $>j then !.a=!.a+1 /* " " abundant " */
else if $>j then !.a=!.a+1 /* " " abundant " */
else !.p=!.p+1 /* " " perfect " */
else !.p=!.p+1 /* " " perfect " */
end /*j*/
end /*j*/


say ' the number of perfect numbers: ' right(!.p, length(high))
say ' the number of perfect numbers: ' right(!.p, length(high))
say ' the number of abundant numbers: ' right(!.a, length(high))
say ' the number of abundant numbers: ' right(!.a, length(high))
say ' the number of deficient numbers: ' right(!.d, length(high))
say ' the number of deficient numbers: ' right(!.d, length(high))
exit /*stick a fork in it, we're done.*/
exit /*stick a fork in it, we're all done. */
/*────────────────────────────────────────────────────────────────────────────*/
/*──────────────────────────────────ISQRT subroutine────────────────────*/
iSqrt: procedure; parse arg x; q=1; r=0; do while q<=x; q=q*4; end
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
do while q>1; q=q%4; _=x-r-q; r=r%2; if _>=0 then do; x=_; r=r+q; end
end /*while q>1*/
end /*while ···*/
return r
return r
/*────────────────────────────────────────────────────────────────────────────*/
/*──────────────────────────────────SIGMA subroutine────────────────────*/
sigma: procedure; parse arg x; odd=x//2 /* [↓] some special cases.*/
sigma: procedure; parse arg x; if x<5 then return max(0,x-1); sqX=iSqrt(x)
s=1; odd=x//2 /* [↓] only use EVEN or ODD integers.*/
if x<5 then do; if x==0 then return 0; return x-1; end
sqX=iSqrt(x) /*calculate the integer square rt*/
do j=2+odd by 1+odd to sqX /*divide by all integers up to x */
if x//j==0 then s=s+j+ x%j /*add the two divisors to (sigma) sum. */
s=1 /* [↓] use only EVEN|ODD integers*/
do j=2+odd by 1+odd to sqX /*divide by all integers up to √x*/
end /*j*/ /* [↑] % is the REXX integer division*/
if x//j==0 then s=s+j+ x%j /*add the two divisors to the sum*/
/* [↓] adjust for a square. ___*/
end /*j*/ /* [↑] % is REXX integer divide*/
if sqx*sqx==x then s=s-j /*Was X a square? If so, subtract x */
/* [↓] adjust for square. _ */
return s /*return (sigma) sum of the divisors. */</lang>
if sqX*sqX==x then s=s-j /*Is X a square? If so, sub √x.*/
return s /*return the sum of the divisors.*/</lang>
'''output''' is the same as the 1<sup>st</sup> version.
'''output''' is the same as the 1<sup>st</sup> version.