Charles.Forsyth20060303a828770d19 years agoHistory
220 lines · 4.0 KB · Brainfuck
RawDownload
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;}