nth_prime: fixed version
This commit is contained in:
parent
14bf87c43f
commit
a8a482b106
1 changed files with 46 additions and 10 deletions
|
|
@ -1,5 +1,6 @@
|
||||||
#include "nth_prime.h"
|
#include "nth_prime.h"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
|
@ -18,7 +19,7 @@ number_t nth(size_t n, size_t sieve_size)
|
||||||
if (n == 1)
|
if (n == 1)
|
||||||
return 2;
|
return 2;
|
||||||
|
|
||||||
vector<number_t> primes = {3, 5, 7, 11, 13};
|
vector<number_t> primes = {3, 5, 7, 11, 13, 17, 19, 23, 29, 31};
|
||||||
|
|
||||||
if (n - 2 < primes.size())
|
if (n - 2 < primes.size())
|
||||||
return primes[n - 2];
|
return primes[n - 2];
|
||||||
|
|
@ -32,24 +33,50 @@ number_t nth(size_t n, size_t sieve_size)
|
||||||
}
|
}
|
||||||
|
|
||||||
vector<char> sieve(sieve_size, false);
|
vector<char> sieve(sieve_size, false);
|
||||||
|
vector<number_t> next(n - 1, 0);
|
||||||
|
|
||||||
sieve[0] = true;
|
sieve[0] = true;
|
||||||
|
|
||||||
size_t first_number = 1;
|
number_t first_number = 1;
|
||||||
|
|
||||||
while (true) {
|
auto create_next = [&first_number](number_t p) -> number_t {
|
||||||
|
|
||||||
for (auto p : primes) {
|
return (p*p - first_number)/2;
|
||||||
|
};
|
||||||
|
|
||||||
size_t reminder = (first_number % (2*p));
|
transform(primes.cbegin(), primes.cend(), next.begin(), create_next);
|
||||||
size_t begin = reminder > p ? 3*p - reminder : p - reminder;
|
|
||||||
|
|
||||||
begin /= 2;
|
for (auto p : primes)
|
||||||
|
sieve[(p - first_number) / 2] = true;
|
||||||
|
|
||||||
for (size_t i = begin; i < sieve_size; i += p) {
|
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;
|
sieve[i] = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
next = i - sieve_size;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
|
||||||
|
for (size_t pn = 0; pn < primes.size(); ++pn) {
|
||||||
|
|
||||||
|
const number_t &p = primes[pn];
|
||||||
|
|
||||||
|
number_t i = next[pn];
|
||||||
|
|
||||||
|
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) {
|
for (size_t i = 0; i < sieve_size; ++i) {
|
||||||
|
|
@ -58,18 +85,27 @@ number_t nth(size_t n, size_t sieve_size)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
number_t p = first_number + 2*i;
|
number_t p = first_number + 2*i;
|
||||||
|
|
||||||
primes.push_back(p);
|
primes.push_back(p);
|
||||||
|
|
||||||
if (primes.size() == n - 1)
|
if (primes.size() == n - 1)
|
||||||
return p;
|
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;
|
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)
|
if (next_first_number < first_number)
|
||||||
throw runtime_error("failed to reach prime number");
|
throw runtime_error("failed to reach prime number");
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue