Perfect numbers: Difference between revisions
Content added Content deleted
m (→Classic REXX version of PL/I: changed a comment.) |
m (→Lucas-Lehmer method: added/changed comments and whitespace.) |
||
Line 1,828: | Line 1,828: | ||
This version uses memoization to implement a fast version of Lucas-Lehmer test, |
This version uses memoization to implement a fast version of Lucas-Lehmer test, |
||
<br>it is faster than the traditional method by an order of magnitude. |
<br>it is faster than the traditional method by an order of magnitude. |
||
<lang rexx>/*REXX program tests if a number (or a range of numbers) is/are perfect.*/ |
<lang rexx>/*REXX program tests if a number (or a range of numbers) is/are perfect. */ |
||
parse arg low high . /*obtain the |
parse arg low high . /*obtain the optional arguments from CL*/ |
||
if high=='' & low=='' then high=34000000 /*if no |
if high=='' & low=='' then high=34000000 /*if no arguments, then use a range. */ |
||
if low=='' then low=1 /*if no LOW, then assume unity.*/ |
if low=='' then low=1 /*if no LOW, then assume unity. */ |
||
low=low+low//2 /*if LOW is odd, bump it by one. */ |
|||
if high=='' then high=low /*if no HIGH, then assume LOW. */ |
if high=='' then high=low /*if no HIGH, then assume LOW. */ |
||
w=length(high) /*use W for formatting output. */ |
w=length(high) /*use W for formatting the output. */ |
||
numeric digits max(9,w+2) /*ensure enough digits to handle |
numeric digits max(9,w+2) /*ensure enough digits to handle number*/ |
||
@.=0; @.1=2 /*highest magic |
@.=0; @.1=2 /*highest magic number and its index. */ |
||
⚫ | |||
if isPerfect(i) then say right(i,w) 'is a perfect number.' |
|||
⚫ | |||
⚫ | |||
/*──────────────────────────────────ISPERFECT subroutine────────────────*/ |
|||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
if isPerfect(i) then say right(i,w) 'is a perfect number.' |
|||
⚫ | |||
⚫ | |||
/*──────────────────────────────────────────────────────────────────────────────────────*/ |
|||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
if @.x==0 then return 0 /*Didn't pass Lucas-Lehmer test? */ |
|||
end /*@.1*/ /*uses memoization for the formula. */ |
|||
⚫ | |||
if @.x==0 then return 0 /*Didn't pass Lucas-Lehmer test? */ |
|||
s = 3 + x%2 /*we know the following factors: */ |
|||
/* 1 ('cause Mama said so.) */ |
|||
/* 2 ('cause it's even.) */ |
|||
/* x÷2 ( " " " ) ___*/ |
|||
do j=3 while j*j<=x /*starting at 3, find the factors ≤√ X */ |
|||
if x//j\==0 then iterate /*J divides X evenly, so ··· */ |
|||
s=s + j + x%j /*··· add it and the other factor. */ |
|||
if s>x then return 0 /*Is the sum too big? It ain't perfect*/ |
|||
⚫ | |||
return s==x /*if the sum matches X, it's perfect!*/</lang> |
|||
'''output''' is the same as the traditional version and is about '''75''' times faster (testing 34,000,000 numbers). |
'''output''' is the same as the traditional version and is about '''75''' times faster (testing 34,000,000 numbers). |
||