Based on this Python answer by Will Ness, I've been using a JavaScript adaptation for the postponed sieve algorithm from that answer:
function * primes() {
yield 2;
yield 3;
yield 5;
yield 7;
const sieve = new Map();
const ps = primes();
ps.next() && ps.next();
for (let p = 3, i = 9; true; i += 2) {
let s = sieve.get(i);
if (s !== undefined) {
sieve.delete(i);
} else if (i < p * p) {
yield i;
continue;
} else {
s = 2 * p;
p = ps.next().value;
}
let k = i + s;
while (sieve.has(k)) k += s;
sieve.set(k, s);
}
}
But now that I need to add start
point to it, I am struggling to wrap my head around it, for the logic here isn't straightforward.
When start
is a prime, I need it to be the first value. And when start
is not a prime, I need the sequence to start with the first prime after start
.
Will Ness suggested in one of the comments:
You would have to come up with the valid sieve dictionary for the start point. It's easy to get the needed primes - just run this algo up to
sqrt(start)
, then you need to find each core prime's multiple just above (or is it just below?) the start, while minding the duplicates.
Wielding this into reality however is not that simple (or at least for me) :|
Can anybody help with updating this algorithm for such *primes(start)
implementation (preferably in JavaScript as above)?
function * primes(start) {
// how to amend it to support 'start' logic???
}
Conclusion
Following the excellent answer by Will Ness, I decided to share the final code I used, through a public library - primes-generator. All main algorithms can be found in src/sieve.ts.
i
?s
?p
? why no comments in the code? – Cephalopod