summaryrefslogtreecommitdiff
path: root/appl/math/sieve.b
diff options
context:
space:
mode:
authorCharles.Forsyth <devnull@localhost>2006-12-22 17:07:39 +0000
committerCharles.Forsyth <devnull@localhost>2006-12-22 17:07:39 +0000
commit37da2899f40661e3e9631e497da8dc59b971cbd0 (patch)
treecbc6d4680e347d906f5fa7fca73214418741df72 /appl/math/sieve.b
parent54bc8ff236ac10b3eaa928fd6bcfc0cdb2ba46ae (diff)
20060303a
Diffstat (limited to 'appl/math/sieve.b')
-rw-r--r--appl/math/sieve.b220
1 files changed, 220 insertions, 0 deletions
diff --git a/appl/math/sieve.b b/appl/math/sieve.b
new file mode 100644
index 00000000..25d4b0f1
--- /dev/null
+++ b/appl/math/sieve.b
@@ -0,0 +1,220 @@
+implement Sieve;
+
+include "sys.m";
+ sys: Sys;
+include "draw.m";
+include "arg.m";
+ arg: Arg;
+
+M: con 16*1024*1024;
+N: con 8*M;
+T: con 2*1024*1024;
+
+limit := array[5] of { M, N, 2*N, 3*N, 15*(N/4) };
+
+Sieve: module
+{
+ init: fn(nil: ref Draw->Context, argv: list of string);
+};
+
+init(nil: ref Draw->Context, argv: list of string)
+{
+ sys = load Sys Sys->PATH;
+ arg = load Arg Arg->PATH;
+
+ np := 0;
+ alg := 3;
+ arg->init(argv);
+ while((c := arg->opt()) != 0){
+ case (c){
+ 'a' =>
+ alg = int arg->arg();
+ }
+ }
+ if(alg < 0 || alg > 4)
+ alg = 3;
+ lim := limit[alg];
+ argv = arg->argv();
+ if(argv != nil)
+ lim = int hd argv;
+ if(lim < 0 || lim > limit[alg])
+ lim = limit[alg];
+ if(lim < 6){
+ if(lim > 2){
+ sys->print("2\n");
+ np++;
+ }
+ if(lim > 3){
+ sys->print("3\n");
+ np++;
+ }
+ }
+ else{
+ case (alg){
+ 0 => np = init0(lim);
+ 1 => np = init1(lim);
+ 2 => np = init2(lim);
+ 3 => np = init3(lim);
+ 4 => np = init4(lim);
+ }
+ }
+ sys->print("%d primes < %d\n", np, lim);
+}
+
+init0(lim: int): int
+{
+ p := array[lim] of byte;
+ for(i := 0; i < lim; i++)
+ p[i] = byte 1;
+ p[0] = p[1] = byte 0;
+ np := 0;
+ for(i = 0; i < lim; i++){
+ if(p[i] == byte 1){
+ np++;
+ sys->print("%d\n", i);
+ for(j := i+i; j < lim; j += i)
+ p[j] = byte 0;
+ }
+ }
+ return np;
+}
+
+init1(lim: int): int
+{
+ n := (lim+31)/32;
+ p := array[n] of int;
+ for(i := 0; i < n; i++)
+ p[i] = int 16rffffffff;
+ p[0] = int 16rfffffffc;
+ np := 0;
+ for(i = 0; i < lim; i++){
+ if(p[i>>5] & (1<<(i&31))){
+ np++;
+ sys->print("%d\n", i);
+ for(j := i+i; j < lim; j += i)
+ p[j>>5] &= ~(1<<(j&31));
+ }
+ }
+ return np;
+}
+
+init2(lim: int): int
+{
+ n := ((lim+1)/2+31)/32;
+ p := array[n] of int;
+ for(i := 0; i < n; i++)
+ p[i] = int 16rffffffff;
+ p[0] = int 16rfffffffe;
+ np := 1;
+ sys->print("%d\n", 2);
+ for(i = 1; i < lim; i += 2){
+ k := (i-1)>>1;
+ if(p[k>>5] & (1<<(k&31))){
+ np++;
+ sys->print("%d\n", i);
+ inc := i+i;
+ for(j := i+i+i; j < lim; j += inc){
+ k = (j-1)>>1;
+ p[k>>5] &= ~(1<<(k&31));
+ }
+ }
+ }
+ return np;
+}
+
+init3(lim: int): int
+{
+ n := ((lim+2)/3+31)/32;
+ p := array[n] of int;
+ for(i := 0; i < n; i++)
+ p[i] = int 16rffffffff;
+ p[0] = int 16rfffffffe;
+ np := 2;
+ sys->print("%d\n", 2);
+ sys->print("%d\n", 3);
+ d := 2;
+ for(i = 1; i < lim; i += d){
+ k := (i-1)/3;
+ if(p[k>>5] & (1<<(k&31))){
+ np++;
+ sys->print("%d\n", i);
+ inc := 6*i;
+ for(j := 5*i; j > 0 && j < lim; j += inc){
+ k = (j-1)/3;
+ p[k>>5] &= ~(1<<(k&31));
+ }
+ for(j = 7*i; j > 0 && j < lim; j += inc){
+ k = (j-1)/3;
+ p[k>>5] &= ~(1<<(k&31));
+ }
+ }
+ d = 6-d;
+ }
+ return np;
+}
+
+init4(lim: int): int
+{
+ n := (4*((lim+14)/15)+31)/32;
+ p := array[n] of int;
+ for(i := 0; i < n; i++)
+ p[i] = int 16rffffffff;
+ p[0] = int 16rfffffffe;
+ np := 3;
+ sys->print("%d\n", 2);
+ sys->print("%d\n", 3);
+ sys->print("%d\n", 5);
+ m := -1;
+ d := array[8] of { 6, 4, 2, 4, 2, 4, 6, 2 };
+ for(i = 1; i < lim; i += d[m]){
+ k := (17*(i%30-1))/60+8*(i/30);
+ if(p[k>>5] & (1<<(k&31))){
+ np++;
+ sys->print("%d\n", i);
+ inc := 30*i;
+ for(j := 7*i; j > 0 && j < lim; j += inc){
+ k = (17*(j%30-1))/60+8*(j/30);
+ p[k>>5] &= ~(1<<(k&31));
+ }
+ for(j = 11*i; j > 0 && j < lim; j += inc){
+ k = (17*(j%30-1))/60+8*(j/30);
+ p[k>>5] &= ~(1<<(k&31));
+ }
+ for(j = 13*i; j > 0 && j < lim; j += inc){
+ k = (17*(j%30-1))/60+8*(j/30);
+ p[k>>5] &= ~(1<<(k&31));
+ }
+ for(j = 17*i; j > 0 && j < lim; j += inc){
+ k = (17*(j%30-1))/60+8*(j/30);
+ p[k>>5] &= ~(1<<(k&31));
+ }
+ for(j = 19*i; j > 0 && j < lim; j += inc){
+ k = (17*(j%30-1))/60+8*(j/30);
+ p[k>>5] &= ~(1<<(k&31));
+ }
+ for(j = 23*i; j > 0 && j < lim; j += inc){
+ k = (17*(j%30-1))/60+8*(j/30);
+ p[k>>5] &= ~(1<<(k&31));
+ }
+ for(j = 29*i; j > 0 && j < lim; j += inc){
+ k = (17*(j%30-1))/60+8*(j/30);
+ p[k>>5] &= ~(1<<(k&31));
+ }
+ for(j = 31*i; j > 0 && j < lim; j += inc){
+ k = (17*(j%30-1))/60+8*(j/30);
+ p[k>>5] &= ~(1<<(k&31));
+ }
+ }
+ m++;
+ if(m == 8)
+ m = 0;
+ }
+ return np;
+}
+
+init5(lim: int): int
+{
+ # you must be joking
+ lim = 0;
+ return 0;
+}