流行

なんか、素数の無限リストを記述するのがはやっているらしい。何が楽しいんだろうか。id:namasute0とかid:letterとか。と、最初に書き出した人間が言うというどうでもいい状況。まあ、正確には最初に書いてたのはkosak氏なんだけどな。

で、そういえば以前Cで無限リストを実装したことがあったのを思い出した。そのソース、まだ残ってるかなあとフォルダの中を探していたら、見事に見つかったので、もう一回さらしてみる。

#include 
#include 
struct cell{
	int value;
	struct cell *next;
	int delay;
	struct cell *(*next_func)(int);
	int arg;
};

struct cell *new_cell(int value){
	struct cell *cell = malloc(sizeof(struct cell));
	cell->value = value;
	cell->next = NULL;
	cell->delay = 0;
	cell->next_func = NULL;
	cell->arg = 0;
	return cell;
}

struct cell *cons(int first, struct cell *c){
	struct cell *f = new_cell(first);
	f->next = c;
	return f;
}

int car(struct cell *c){
	//if(c->delay){
	//	c->value = c->next_func(c->arg);
	//	c->delay = 0;
	//}
	return c->value;
}

struct cell *cdr(struct cell *c){
	if(c->delay){
		c->next = c->next_func(c->arg);
		c->delay = 0;
	}
	return c->next;
}

struct cell *append(struct cell *f, struct cell *n){
	if(f == NULL){
		return n;
	}else{
		return cons(car(f), append(cdr(f), n));
	}
}

struct cell *reverse(struct cell *c){
	if(c == NULL){
		return NULL;
	}else{
		return append(reverse(cdr(c)), new_cell(c->value));
	}
}

struct cell *add_last(struct cell *c, int value){
	if(c == NULL){
		return new_cell(value);
	}else{
		return append(c, add_last(cdr(c), value));
	}
}


struct cell *start_n_prime(int n){
	while(1){
		int flg2 = 0;
		int i;
		for(i = 2; i*i <= n; i++){
			if(n % i == 0){
				flg2 = 1;
				break;
			}
		}
		if(!flg2){
			break;
		}
		n++;
	}
	struct cell *c = new_cell(n);
	c->delay = 1;
	c->next_func = start_n_prime;
	c->arg = n+1;
	return c;
}


int main(){
	struct cell *c = start_n_prime(1);
	struct cell *d = c;
	int i;
	
	//int t1 = time(NULL);
	for(i = 0; i < 100; i++){
		printf("%d\n", car(d));
		d = cdr(d);
	}
}