diff --git a/cpp/nth-prime/nth_prime.cpp b/cpp/nth-prime/nth_prime.cpp index f4089e6..323f606 100644 --- a/cpp/nth-prime/nth_prime.cpp +++ b/cpp/nth-prime/nth_prime.cpp @@ -1,5 +1,6 @@ #include "nth_prime.h" +#include #include #include #include @@ -18,7 +19,7 @@ number_t nth(size_t n, size_t sieve_size) if (n == 1) return 2; - vector primes = {3, 5, 7, 11, 13}; + vector primes = {3, 5, 7, 11, 13, 17, 19, 23, 29, 31}; if (n - 2 < primes.size()) return primes[n - 2]; @@ -31,25 +32,51 @@ number_t nth(size_t n, size_t sieve_size) size_t(0.5*(n * (log(n) + log(log(n)))) + 0.5)); } - vector sieve(sieve_size, false); + vector sieve(sieve_size, false); + vector next(n - 1, 0); sieve[0] = true; - size_t first_number = 1; + number_t first_number = 1; + + auto create_next = [&first_number](number_t p) -> number_t { + + return (p*p - first_number)/2; + }; + + transform(primes.cbegin(), primes.cend(), next.begin(), create_next); + + for (auto p : primes) + sieve[(p - first_number) / 2] = true; + + auto process_prime = [sieve_size,&sieve](const number_t &p, number_t &next) { + + number_t i = next; + + for (; i < sieve_size; i += p) { + + sieve[i] = true; + } + + next = i - sieve_size; + }; + while (true) { - for (auto p : primes) { + for (size_t pn = 0; pn < primes.size(); ++pn) { - size_t reminder = (first_number % (2*p)); - size_t begin = reminder > p ? 3*p - reminder : p - reminder; + const number_t &p = primes[pn]; - begin /= 2; + number_t i = next[pn]; - for (size_t i = begin; i < sieve_size; i += p) { + for (; i < sieve_size; i += p) { sieve[i] = true; } + + next[pn] = i - sieve_size; +// process_prime(primes[pn], next[pn]); } for (size_t i = 0; i < sieve_size; ++i) { @@ -58,18 +85,27 @@ number_t nth(size_t n, size_t sieve_size) continue; number_t p = first_number + 2*i; + primes.push_back(p); if (primes.size() == n - 1) return p; - for (size_t j = i; j < sieve_size; j += p) { + next[primes.size() - 1] = create_next(p);//(p*p - first_number)/2; + + sieve[i] = true; + + number_t j = next[primes.size() - 1]; + + for (; j < sieve_size; j += p) { sieve[j] = true; } + + next[primes.size() - 1] = j - sieve_size; } - size_t next_first_number = first_number + 2*sieve_size; + number_t next_first_number = first_number + 2*sieve_size; if (next_first_number < first_number) throw runtime_error("failed to reach prime number");