#include <iostream>
#include <list>
// Disclaimer. I read the Sieve of Eratosthenes wikipedia article.
int main() {
std::list<unsigned int> prime_list(1, 2);
std::list<unsigned int>::iterator prime_iter;
unsigned int n;
unsigned int list_num = 0;
std::list<unsigned int> number_list;
std::list<unsigned int>::iterator number_iter;
while(true) {
n = list_num * 100000 + 2;
number_list.clear();
// Build the next 100k numbers.
while(n < (list_num + 1) * 100000 + 2) {
number_list.push_back(n);
++n;
}
// Sieve with what we already have.
for(prime_iter = prime_list.begin(); prime_iter != prime_list.end(); ++prime_iter) {
if(*prime_iter * *prime_iter > number_list.back()) break;
number_iter = number_list.begin();
while(number_iter != number_list.end()) {
if(*number_iter % *prime_iter == 0) {
number_iter = number_list.erase(number_iter);
}
else {
++number_iter;
}
}
}
while(prime_list.back() * prime_list.back() < number_list.back()) {
prime_list.push_back(number_list.front());
number_list.pop_front();
// Sieve using the new prime.
number_iter = number_list.begin();
while(number_iter != number_list.end()) {
if(*number_iter % prime_list.back() == 0) {
number_iter = number_list.erase(number_iter);
}
else {
++number_iter;
}
}
}
// The rest of the numbers are primes as well.
prime_list.splice(prime_list.end(), number_list);
if(prime_list.size() > 10000) {
prime_iter = prime_list.begin();
n = 1;
while(n != 10001) {
++prime_iter;
++n;
}
std::cout << *prime_iter << std::endl;
return 0;
}
++list_num;
}
}