示例#1
0
文件: sets.c 项目: wrpaape/euler
/************************************************************************
 *				HELPERS					*
 ************************************************************************/
void *sieve_range(void *arg)
{
	bool (*flip_fun)(const int, struct SquareTerms *);
	struct IntNode *cand;

	struct SieveArg *params = (struct SieveArg *) arg;
	struct IntNode **prv    = &params->head;
	const int until		= params->until;
	/*
	 * case where x will be largest corresponds to the third flipping
	 * quadratic:
	 *
	 * 3x² - y² = n  where x > y
	 *
	 * when y = one less than x = (x - 1)
	 *
	 * substituting:
	 *
	 * 3x² - (x - 1)² = n
	 * 2x² + 2x - (1 + n) = 0
	 *
	 * from quadratic equation:
	 * x_max = (-1 + sqrt(3 + 2n)) / 2
	 *
	 * add one to ensure that range of x includes x_max:
	 */
	const int LENGTH_TERMS =
		((((int) sqrtf((float) ((until * 2) + 3))) - 1) / 2) + 1;

	int x_sq_3[LENGTH_TERMS];
	int x_sq_4[LENGTH_TERMS];

	for (int x = 2, x_sq; x < LENGTH_TERMS; ++x) {
		x_sq = x * x;
		x_sq_3[x] = 3 * x_sq;
		x_sq_4[x] = 4 * x_sq;
	}

	struct SquareTerms SQ_TERMS = {
		.X_SQ_3 = x_sq_3,
		.X_SQ_4 = x_sq_4
	};

	for (int n = params->start; n < until; n+=2) {

		flip_fun = FLIP_MAP[n % 60];

		if (flip_fun && flip_fun(n, &SQ_TERMS)) {
			cand = handle_malloc(sizeof(struct IntNode));
			cand->val = n;
			*prv = cand;
			prv  = &cand->nxt;
		}
	}

	params->last = cand;

	pthread_exit(NULL);
}
示例#2
0
文件: sets.c 项目: wrpaape/euler
struct IntNode *prime_sieve(const int sup)
{
	struct IntNode *primes = handle_malloc(sizeof(struct IntNode));
	struct IntNode *num;
	struct IntNode *prv;
	struct IntNode *prime;
	int prime_val;

	num = primes;
	num->val = 2;

	/* initialize sieve to all odd numbers between '2' and input supremum 'sup' */
	for (int odd = 3; odd < sup; odd += 2) {
		num->nxt = handle_malloc(sizeof(struct IntNode));
		num = num->nxt;
		num->val = odd;
	}

	num->nxt = NULL;

	for (prime = primes->nxt; prime != NULL; prime = prime->nxt) {

		prime_val = prime->val;
		prv = prime;
		num = prv->nxt;

		while (num != NULL) {

			if (num->val % prime_val == 0) {
				prv->nxt = num->nxt;
				free(num);
				num = prv->nxt;
			} else {
				prv = num;
				num = num->nxt;
			}
		}
	}

	return primes;
}
示例#3
0
文件: sets.c 项目: wrpaape/euler
struct IntNode *atkin_sieve(const int sup)
{
	pthread_t sieve_threads[4];
	struct SieveArg args[4];
	struct IntNode *primes;
	struct IntNode *prime;
	struct IntNode *prev;
	struct IntNode *cand;
	int q_i;
	int start;
	int prime_val;
	int sq_val;
	int mult_val;
	int mult_sq;
	const int DELTA = (sup - 13) / 4;

	/* initialize result list 'primes' with first 5 prime numbers */
	primes = handle_malloc(sizeof(struct IntNode) * 5);
	prime  = primes;
	prime->val = 2; prime->nxt = prime + 1; ++prime;
	prime->val = 3; prime->nxt = prime + 1; ++prime;
	prime->val = 5; prime->nxt = prime + 1; ++prime;
	prime->val = 7; prime->nxt = prime + 1; ++prime;
	prime->val = 11;

	/* split range into 4 intervals and sieve in parallel */
	for (q_i = 0, start = 13; q_i < 3; ++q_i) {
		args[q_i].start = start;
		start	       += DELTA;
		args[q_i].until = start;

		handle_pthread_create(&sieve_threads[q_i],
				      NULL,
				      sieve_range,
				      (void *) &args[q_i]);
	}

	/* ensure final sieve interval ends at input supremum 'sup' */
	args[3].start = start;
	args[3].until = sup;

	handle_pthread_create(&sieve_threads[3],
			      NULL,
			      sieve_range,
			      (void *) &args[3]);

	/* await threads, join candidates and append to 'primes' */
	handle_pthread_join(sieve_threads[0], NULL);
	prime->nxt = args[0].head;
	cand	   = args[0].last;

	for (q_i = 1; q_i < 4; ++q_i) {
		handle_pthread_join(sieve_threads[q_i], NULL);
		cand->nxt = args[q_i].head;
		cand	  = args[q_i].last;
	}

	cand->nxt = NULL;
	const int SQ_CUTOFF = cand->val;

	/* starting at node 7... */
	--prime;
	prime_val = 7;
	sq_val	  = 49;

	while (1) {
		prev    = prime;
		cand    = prime->nxt;
		mult_sq = sq_val;

		while (1) {
			if (cand->val < mult_sq) {
				prev = cand;
				cand = cand->nxt;
				continue;
			}

			if (cand->val == mult_sq) {
				prev->nxt = cand->nxt;
				free(cand);
				cand = prev->nxt;

			} else {
				prev = cand;
				cand = cand->nxt;
			}

			mult_sq += sq_val;

			if (mult_sq > SQ_CUTOFF)
				break;
		}


		prime	  = prime->nxt;
		prime_val = prime->val;
		sq_val	  = prime_val * prime_val;

		if (sq_val > SQ_CUTOFF)
			return primes;
	}
}
示例#4
0
文件: config.c 项目: jrnutt/msged
static void _pascal parsemail(char *keyword, char *value)

{
	char *s = value;
	char *e = NULL;
	AREA *t;
	AREA a;

	check(username);
	memset(&a,0,sizeof a);

	switch (tolower(*keyword)) { /* one letter is enough for now */
		default  :
		case 'f' : a.msgtype = FIDO; break;
		case 'q' : a.msgtype = QUICK; break;
	}

	while (*s && isspace(*s)) s++;
	if (!*s) return;

	switch (tolower(*s)) { /* one letter is enough */
		case 'n' : a.news = 1; break;
		case 'u' : a.uucp = 1; break;
		case 'm' : a.netmail = 1; break;
		case 'e' : a.echomail = 1; break;
		case 'l' :
		default  : a.local = 1; break;
	}

	while (*s && !isspace(*s)) s++;  /* skip the rest */
	while (*s && isspace(*s)) s++;
	if (!*s) return;

	if (*s != '\"') {
		while (*s && !isspace(*s)) {
			switch (tolower(*s)) {
				case 'p' : a.priv = 1; break;
				case 'h' : a.hold = 1; break;
				case 'd' : a.direct = 1; break;
				case 'c' : a.crash = 1; break;
				case 'k' : a.killsent = 1; break;
				case  0  : return;
			}
			s++;
		}
		while (*s && isspace(*s)) s++;
		if (!*s) return;
	}

	if ((e = strchr(++s,'\"')) == NULL) return;
	*e++ = '\0';
	a.description = strdup(s);
	s = e;

	while (*s && isspace(*s)) s++;
	if (!*s) {
		free(a.description);
		return;
	}

	if ((e = strchr(s,' ')) == NULL)
		e = strchr(s,'\t');

	if (e == NULL)
		e = s;
	else
		*e++ = '\0';

	while (*s && isspace(*s)) s++;
	if (!*s) {
		free(a.description);
		return;
	}

	switch (a.msgtype) {
		default :
		case FIDO  : a.path = strdup(strlwr(s)); break;
		case QUICK : a.board = atoi(s); break;
	}

	if (a.msgtype == FIDO) {
		if (chdir(a.path) != 0) {
			free(a.path);
			free(a.description);
			return;
		}
		else
			setcwd(home);
	}

	if (a.echomail) {
		s = e;
		while (*s && isspace(*s)) s++;
		if (s && *s)
			a.tag = strdup(s);
		else
			a.tag = NULL;
	}

	for (area = 0; area < areas; area++) {
		/* this is a sneaky use of the ternary operator */

		if (((a.msgtype == QUICK) && (arealist[area].msgtype == QUICK))?
			(a.board == arealist[area].board):
			(strcmp(a.path,arealist[area].path)==0)) {
				arealist[area].priv |= a.priv;
				arealist[area].hold |= a.hold;
				arealist[area].direct |= a.direct;
				arealist[area].crash |= a.crash;
				arealist[area].killsent |= a.killsent;
				arealist[area].news |= a.news;
				arealist[area].echomail |= a.echomail;
				arealist[area].uucp |= a.uucp;
				arealist[area].netmail |= a.netmail;
				arealist[area].local |= a.local;

				if (arealist[area].description == NULL)
					arealist[area].description = a.description;
				else if (a.description)
					free(a.description);

				if (arealist[area].tag == NULL)
					arealist[area].tag = a.tag;
				else if (a.tag)
					free(a.tag);

				if ((a.msgtype == FIDO) && (a.path))
					free(a.path);

				return;
		}
	}

	areas++;
	area = areas - 1;

	check(username);

	if (arealist == NULL)
		arealist = handle_malloc(areas * sizeof(struct _area));
	else {
		check(username);
		arealist = handle_realloc(arealist, areas * sizeof(struct _area));
		check(username);
	}

	check(username);

	if (arealist == NULL)
		outamemory();

	check(username);
	checkp(arealist);
	t = arealist + area;
	checkp(t);
	checkp(arealist);
	check(username);
	*t = a;
	checkp(t);
	check(username);
}