94 lines
3.3 KiB
Text
94 lines
3.3 KiB
Text
Module CheckPrimes {
|
|
\\ Inventories are lists, Known and Known1 are pointers to Inventories
|
|
Inventory Known=1:=2@,2:=3@,3:=5@
|
|
Inventory Known1=2@, 3@, 5@
|
|
\\ In a lambda all closures are copies
|
|
\\ but Known and Know1 are copies of pointers
|
|
\\ so are closures like by reference
|
|
PrimeNth=lambda Known, Known1 (n as long) -> {
|
|
if n<1 then Error "Only >=1"
|
|
if exist(known, n) then =eval(known) : exit
|
|
if n>5 then {
|
|
i=len(known1)
|
|
x=eval(known1, i-1)+2
|
|
} else x=5 : i=2
|
|
{
|
|
if i=n then =known(n) : exit
|
|
ok=false
|
|
if frac(x) then 1000
|
|
if frac(x/2) else 1000
|
|
if frac(x/3) else 1000
|
|
x1=sqrt(x) : d=5@
|
|
Repeat
|
|
if frac(x/d ) else exit
|
|
d += 2: if d>x1 then ok=true : exit
|
|
if frac(x/d) else exit
|
|
d += 4: if d<= x1 else ok=true: exit
|
|
Always
|
|
1000 If ok then i++:Append Known, i:=x : if not exist(Known1, x) then Append Known1, x
|
|
x+=2 : Loop }
|
|
}
|
|
\\ IsPrime has same closure, Known1
|
|
IsPrime=lambda Known1 (x as decimal) -> {
|
|
if exist(Known1, x) then =true : exit
|
|
if Eval(Known1, len(Known1)-1)>x then exit
|
|
if frac(x/2) else exit
|
|
if frac(x/3) else exit
|
|
x1=sqrt(x):d = 5@
|
|
{if frac(x/d ) else exit
|
|
d += 2: if d>x1 then =true : exit
|
|
if frac(x/d) else exit
|
|
d += 4: if d<= x1 else =true: exit
|
|
loop
|
|
}
|
|
}
|
|
\\ fill Known1, PrimeNth is a closure here
|
|
IsPrime2=lambda Known1, PrimeNth (x as decimal) -> {
|
|
if exist(Known1, x) then =true : exit
|
|
i=len(Known1)
|
|
if Eval(Known1, i-1)>x then exit
|
|
{
|
|
z=PrimeNth(i)
|
|
if z<x then loop else.if z=x then =true :exit
|
|
i++
|
|
}
|
|
}
|
|
Print "First twenty primes"
|
|
n=PrimeNth(20)
|
|
For i=1 to 20 : Print Known(i),: Next i
|
|
Print
|
|
Print "Primes between 100 and 150:"
|
|
c=0
|
|
For i=100 to 150
|
|
If IsPrime2(i) Then print i, : c++
|
|
Next i
|
|
Print
|
|
Print "Count:", c
|
|
Print "Primes between 7700 and 8000:"
|
|
c=0
|
|
For i=7700 to 8000
|
|
If IsPrime(i) Then print i, : c++
|
|
Next i
|
|
Print
|
|
Print "Count:", c
|
|
Print "200th Prime:"
|
|
Print PrimeNth(200)
|
|
Print "List from 190th to 199th Prime:"
|
|
For i=190 to 199 : Print Known(i), : Next i
|
|
Print
|
|
Print "Wait"
|
|
Refresh ' because refresh happen on next Print, which take time
|
|
' using set fast! we get no respond from GUI/M2000 Console
|
|
' also Esc, Break and Ctrl+C not work
|
|
' we have to use Refresh each 500 primes to have one Refresh
|
|
Set fast !
|
|
for i=500 to 10000 step 50: m=PrimeNth(i): Print "."; :Refresh:Next i
|
|
Print
|
|
Print "10000th Prime:", PrimeNth(10000)
|
|
' reset speed to fast (there are three levels: slow/fast/fast!)
|
|
set fast
|
|
Print
|
|
Rem 1 : Print Known
|
|
Rem 2: Print Known1
|
|
}
|
|
CheckPrimes
|