RosettaCodeData/Task/Extensible-prime-generator/M2000-Interpreter/extensible-prime-generator-1.m2000
2023-07-01 13:44:08 -04:00

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