#include <vector>
#include <deque>
#include <math.h>
#include <time.h>
#include "../generator.h"
template <typename Primes>
generator(gen_map, unsigned, gen_map<Primes>)
{
const unsigned p0_, p1_, lo_, hi_, bound_;
std::vector<bool> arr_;
unsigned i_, n_;
static unsigned correct(unsigned n, unsigned i)
{ return n & 1 ? n : n + i; }
public:
gen_map(unsigned p0, unsigned p1)
: p0_(p0), p1_(p1)
, lo_(p0 * p0), hi_(p1 * p1)
, bound_((hi_ - lo_) / 2 - 1)
, arr_(bound_ + 1, true)
{
Primes ps(3);
for (ps.next(); ps.value() < p1_; ps.next())
{
const unsigned i = ps.value();
for (unsigned j = (correct(lo_ - lo_ % i + i, i) - lo_) / 2
; j <= bound_
; j += i)
arr_[j] = false;
}
}
emit(unsigned)
{
for (i_ = 1, n_ = lo_ + 2; i_ <= bound_; ++i_, n_ += 2)
{
if (!arr_[i_])
continue;
yield(n_);
}
}
stop_emit()
};
inline unsigned sqrt_int(unsigned x)
{ return static_cast<unsigned>(sqrt(static_cast<double>(x))); }
generator(primes, unsigned, primes)
{
const unsigned n_, sq_n_;
gen_map<primes> *gmap_;
unsigned p0_, p1_, i_;
primes *ps_;
void dispose()
{
if (gmap_)
delete gmap_;
gmap_ = 0;
}
public:
primes(unsigned n = 2)
: n_(n)
, sq_n_(sqrt_int(n))
, gmap_(0)
, ps_(0)
{
}
~primes()
{
dispose();
if (ps_)
delete ps_;
}
emit(unsigned)
{
if (n_ <= 2) yield(2);
if (n_ <= 3) yield(3);
if (n_ <= 5) yield(5);
if (n_ <= 7) yield(7);
ps_ = new primes(3);
ps_->next();
p1_ = ps_->value();
for (;;)
{
p0_ = p1_;
ps_->next();
p1_ = ps_->value();
if (p1_ <= sq_n_)
continue;
dispose();
gmap_ = new gen_map<primes>(p0_, p1_);
while (gmap_->next())
if (gmap_->value() >= n_)
yield(gmap_->value());
}
}
stop_emit()
};
int main()
{
primes ps(100000000);
int sum = 0;
long tim0 = clock();
for (ps.next(); ps.value() <= 120000000; ps.next(), ++sum);
printf("sum = %d, time: %g sec.\n", sum, (clock() - tim0) / 1000.0);
} |