#include #include #include #include #include struct primes { unsigned long int num; struct primes *next; }; void signal_handler( int ); void dump( struct primes *p, unsigned long int n, unsigned long int count, short int prime_cache ); unsigned long int undump( struct primes *p, unsigned long int *n,unsigned long int count, unsigned long int ntrack, FILE *DUMPER, unsigned long int h_num ); void print_last( struct primes *p ); void add_prime( unsigned long int number, struct primes *p ); int try_prime( unsigned long int num, struct primes *p, short int c ); void slow_cache( unsigned long int number ); int try_cache( unsigned long int number ); #define runtime (finish - start) #define cache_limit 1800 FILE *DUMPME, *SLOWCACHE; short int end = 0; int main(int argc, char ** argv) { short int prime_cache = 1; int result, cont; struct primes *p; unsigned long int number, n = 0, count = 0, *nptr; time_t start, finish; nptr = &n; signal( SIGINT, signal_handler ); unlink("./prime.cache"); p = (struct primes *) malloc (sizeof(struct primes)); p -> num = 0; time(&start); fflush(stdout); DUMPME = fopen("prime.dump", "a+"); rewind(DUMPME); printf ("Loading nodes."); for (number = undump(p, nptr, 0, 0, DUMPME, 1); number > 0; number++) { if (end) { fflush(stdin); printf ("Last prime found was \n"); print_last(p); printf ("Continue Crunching? [yn]: "); while (cont != 'y' && cont != 'n') { cont = getc(stdin); if (cont == 'n') { time(&finish); DUMPME = fopen("prime.dump", "w"); printf ("\nDumping primes...\n"); dump(p, n, count, prime_cache); printf ("Numbers per second: %i\n", (number + 1) / runtime); printf ("Elapsed time (actually crunching): %i seconds\n", runtime); exit(1); } } cont = 0; end = 0; } result = try_prime(number, p, prime_cache); if (result) { fflush (stdout); count++; if (count == 1000) { printf ("."); count = 0; n++; if (n == cache_limit) { // n * 1000 * 4 = RAM ALLOWED. 50 Won't affect num < 479903 prime_cache = 0; printf ("\nSwitching to virtual ram.\n"); printf ("Prime Crunching"); fflush(stdout); } } if (prime_cache) { add_prime(number, p); } else { slow_cache(number); } } } time(&finish); DUMPME = fopen("prime.dump", "w"); printf ("\nDumping primes...\n"); dump(p, n, count, prime_cache); printf ("Numbers per second: %i\n", (number + 1) / runtime); printf ("Elapsed time (actually crunching): %i seconds\n", runtime); return 0; } void slow_cache( unsigned long int number ) { SLOWCACHE = fopen("prime.cache", "a"); fprintf (SLOWCACHE, "%li\n", number); fclose(SLOWCACHE); } int try_cache( unsigned long int number ) { unsigned long int i; SLOWCACHE = fopen("prime.cache", "r"); while ( 1 == fscanf(SLOWCACHE, "%li", &i) ) { if (!(number % i)) { return 0; } } fclose (SLOWCACHE); return 1; } unsigned long int undump( struct primes *p, unsigned long int *n, unsigned long int count, unsigned long int ntrack, FILE *DUMPER, unsigned long int h_num) { if (1 == fscanf(DUMPER, "%li", &p -> num)) { h_num = p -> num; p -> next = (struct primes *) malloc (sizeof(struct primes)); p -> next -> num = 0; if (end) { exit(1); } count++; ntrack++; // used to track cache limit if (ntrack == 1000) { *n += 1; // weird pointer thingy w/ p++ fflush(stdout); printf ("."); ntrack = 0; } undump(p -> next, n, count, ntrack, DUMPER, h_num); } else { fclose (DUMPER); printf ("\nCache: %liK out of %liK allowed have been filled\n", *n *1000 * sizeof(struct primes), cache_limit * 1000 * sizeof(struct primes)); if (count > 0) { printf ("Loaded %li nodes. Highest prime %li\nPrime Crunching", count, h_num); return ++h_num; } else { printf("Starting with number 1.\nPrime Crunching"); return 1; } } } void add_prime ( unsigned long int number, struct primes *p ) { if ( p -> num == 0 ) { p -> num = number; p -> next = (struct primes *) malloc (sizeof(struct primes)); p -> next -> num = 0; } else { add_prime( number, p -> next ); } } void print_last ( struct primes *p ) { if ( p -> next -> num == 0 ) { printf ("%li\n", p -> num); } else { print_last( p -> next ); } } void dump( struct primes *p, unsigned long int n, unsigned long int count, short int prime_cache ) { unsigned long int number; for (; p -> num != 0; p = p -> next) { fprintf (DUMPME, "%li\n", p -> num); } if (!prime_cache) { SLOWCACHE = fopen("prime.cache", "r"); while ( 1 == fscanf (SLOWCACHE, "%li", &number) ) fprintf (DUMPME, "%li\n", number); } printf ("Primes found: %i\n", (n * 1000) + count); fclose (DUMPME); } int try_prime( unsigned long int n, struct primes *p, short int c ) { if (n == 1) return 1; if ( p -> num > (n / 2) ) { return 1; } while (p -> num != 0) { if ( !(n % p -> num) && p -> num != 1 ) { return 0; } else { if (try_prime(n, p -> next, c)) { if (c) { return 1; } else { return try_cache(n); } } else { return 0; } } } } void signal_handler( int SignalType ) { printf ("Caught SIGINT.\n"); end = 1; }