This program first publish here
Use Revision 20 (bug on ELSE <number labels> fixed)
Now we can make a bigger computation using Fast! mode which eliminate Gui/console refresh to gain speed. We can make a refresh each 50primes, so we have a tiny delay on refreshing if we move a window above M2000 console.
Also I change IsPrime to not add to Inventory Known1, because we want this inventory to have all primes without any missing until the last one.
I provide another IsPrime2 which use PrimeNth to add to Known1.
Inventories are reference type. Lambda functions are value type, but closures which are reference type copied the reference by value, so we get then by reference. Inventories start now with 3 known primes, and PrimeNth works for odd numbers only (see x+=2 before the loop statement)
Loop statement check a flag in a block of code ({ }), so when the block ends restart again (resetting the loop flag)
And this is the code for optimization for PrimeNth()
Use Revision 20 (bug on ELSE <number labels> fixed)
Now we can make a bigger computation using Fast! mode which eliminate Gui/console refresh to gain speed. We can make a refresh each 50primes, so we have a tiny delay on refreshing if we move a window above M2000 console.
Also I change IsPrime to not add to Inventory Known1, because we want this inventory to have all primes without any missing until the last one.
I provide another IsPrime2 which use PrimeNth to add to Known1.
Inventories are reference type. Lambda functions are value type, but closures which are reference type copied the reference by value, so we get then by reference. Inventories start now with 3 known primes, and PrimeNth works for odd numbers only (see x+=2 before the loop statement)
Loop statement check a flag in a block of code ({ }), so when the block ends restart again (resetting the loop flag)
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
\\ 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 "Primes between 100 and 150:"
c=0
For i=100 to 150
If IsPrime2(i) Then print i, : c++
Next i
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 "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 "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 "10000th Prime:", PrimeNth(10000)
' reset speed to fast (there are three levels: slow/fast/fast!)
set fast
Rem 1 : Print Known
Rem 2: Print Known1
}
CheckPrimes
First twenty primes 2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 Primes between 100 and 150: 101 103 107 109 113 127 131 137 139 149 Count: 10 Primes between 7700 and 8000: 7703 7717 7723 7727 7741 7753 7757 7759 7789 7793 7817 7823 7829 7841 7853 7867 7873 7877 7879 7883 7901 7907 7919 7927 7933 7937 7949 7951 7963 7993 Count: 30 200th Prime: 1223 List from 190th to 199th Prime: 1151 1153 1163 1171 1181 1187 1193 1201 1213 1217 Wait .... (truncate for output) 10000th Prime: 104729
And this is the code for optimization for PrimeNth()
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
if frac(x) then 999
if frac(x/2) else 999
if frac(x/3) else 999
x1=sqrt(x) : d=5@
{if frac(x/d ) else 999
d += 2: if d>x1 then 1000
if frac(x/d) else 999
d += 4: if d<= x1 else 1000
loop
}
999 x++ : Restart
1000 i++:Append Known, i:=x : if not exist(Known1, x) then Append Known1, x
x++ : Loop }
}
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
if frac(x) then 999
if frac(x/2) else 999
if frac(x/3) else 999
x1=sqrt(x) : d=5@
{if frac(x/d ) else 999
d += 2: if d>x1 then 1000
if frac(x/d) else 999
d += 4: if d<= x1 else 1000
loop
}
999 x++ : Restart
1000 i++:Append Known, i:=x : if not exist(Known1, x) then Append Known1, x
x++ : Loop }
}
Δεν υπάρχουν σχόλια:
Δημοσίευση σχολίου
You can feel free to write any suggestion, or idea on the subject.