Perfect numbers: Difference between revisions

m
→‎optimized using only even numbers: added/changed comments and whitespace.
m (→‎traditional method: added/changed comments and whitespace.)
m (→‎optimized using only even numbers: added/changed comments and whitespace.)
Line 1,792:
 
===optimized using only even numbers===
This REXX version uses the fact that all   ''known''   perfect numbers are   ''even''.
<lang rexx>/*REXX program tests if a number (or a range of numbers) is/are perfect. */
parse arg low high . /*obtain theoptional specifiedarguments from the number(s).CL*/
if high=='' & low=='' then high=34000000 /*if no argsargu,ents, then use a range. */
if low=='' then low=1 /*if no LOW, then assume unity. */
if low=low+low//2 then low=low+1 /*if LOW is odd, bump it by one. */
if high=='' then high=low /*if no HIGH, then assume LOW. */
w=length(high) /*use W for formatting the output. */
numeric digits max(9,w+2) /*ensure enough digits to handle# number*/
 
do i=low to high by 2 /*process the single #number or a range. */
if isPerfect(i) then say right(i,w) 'is a perfect number.'
end /*i*/
exit /*stick a fork in it, we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
/*──────────────────────────────────ISPERFECT subroutine────────────────*/
isPerfect: procedure; parse arg x 1 y /*getobtain the number to be tested. */
if x==6 then return 1 /*handle the special case of six. */
 
do until y<10 /*find the digital root of Y. */
parse var y 1 r 2; do k=2 for length(y)-1; r=r+substr(y,k,1); end /*k*/
y=r /*find digital root of digthe root.digital root*/
end /*DO until*/ /*wash, rinse, repeat ··· */
 
if r\==1 then return 0 /*is digDigital root ¬ 1 ? Then ¬ perfect.*/
s=3 + x%2 /*the first 3 factors of X. ___*/
 
s = 3 + x%2 do j=3 while j*j<=x /*thestarting firstat 3, factors of X.find the factors ≤√ X _*/
doif x//j\==30 then iterate while j*j<=x /*startingJ at 3isn't a factor o f X, find factorsso skip ≤√Xit.*/
ifs = s + j + x//%j\==0 then iterate /*J isn't a··· factoradd ofit X, soand skip the other factor. */
if s>x = sthen return 0 + j + x%j /*···Is addthe itsum andtoo thebig? It otherain't factorperfect*/
ifend /*j*/ s>x then return 0 /*Sum(above) is marginally faster. too big? It ain't perfect.*/
return s==x end /*j*/ /*(above)if sum ismatches marginally faster.X, then it's perfect!*/</lang>
return s==x /*if the sum matches X, perfect! */</lang>
'''output''' &nbsp; is the same as the traditional version &nbsp; and is about '''11.5''' times faster &nbsp; (testing 34,000,000 numbers).