Skip to content

Instantly share code, notes, and snippets.

@olamedia
Last active July 29, 2020 16:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save olamedia/7d70c5638315a1f456300bfaa6a2ab55 to your computer and use it in GitHub Desktop.
Save olamedia/7d70c5638315a1f456300bfaa6a2ab55 to your computer and use it in GitHub Desktop.
export const {scan, isPrime, primes} = (() => {
let primes: number[] = [2];
let cursor = 2;
const chunkSize = 100;
const isPrimeAgainstKnown: (number: number) => boolean = number => primes.reduce((result, prime) => {
return result && (number % prime !== 0)
}, true)
async function nextPrime(limit: number): Promise<number|null>{
for (; cursor <= limit; cursor++) {
if (isPrimeAgainstKnown(cursor)){
primes.push(cursor);
return cursor;
}
}
}
async function scanUntil(limit: number): Promise<void>{
return new Promise((resolve, reject) => {
async function scanChunk(){
if (cursor >= limit){
return resolve();
}
const chunkLimit = Math.min(cursor + chunkSize, limit);
const prime = await nextPrime(chunkLimit);
setTimeout(scanChunk, 0)
}
scanChunk()
});
}
async function scanUntil4(limit: number): Promise<void> {
const timeout = 10; // 10ms -> ~650-700ms, 5ms -> 827ms (2..10000)
return new Promise((resolve, reject) => {
(async function loop() {
const before = Date.now();
while (cursor < limit && Date.now() - before < timeout){
await nextPrime(Math.min(cursor + chunkSize, limit));
}
if (cursor >= limit) {
return resolve();
}
nextTick(loop);
})()
});
}
const isPrime = async(number: number):Promise<boolean> => {
if (number < 2 && number % 1 !== 0){
return false;
}
await scanUntil4(number)
return primes.includes(number)
}
return {
scan,
isPrime,
primes: () => primes
}
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment