You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
94 lines
2.2 KiB
JavaScript
94 lines
2.2 KiB
JavaScript
function doUntil(loop, stopCondition, yieldCondition) {
|
|
|
|
// Wrap function in promise so it can run asynchronously
|
|
return new Promise((resolve, reject) => {
|
|
|
|
// Build outerLoop function to pass to setTimeout
|
|
let outerLoop = function () {
|
|
while (true) {
|
|
|
|
// Execute a single inner loop iteration
|
|
loop();
|
|
|
|
if (stopCondition()) {
|
|
// Resolve promise, exit outer loop, and do not re-enter
|
|
resolve();
|
|
break;
|
|
} else if (yieldCondition()) {
|
|
// Exit outer loop and queue up next outer loop iteration
|
|
// for next event cycle
|
|
setTimeout(outerLoop, 0);
|
|
break;
|
|
}
|
|
|
|
// Continue to next inner loop iteration without yielding
|
|
}
|
|
};
|
|
|
|
// Start the first iteration of outer loop, unless the stop condition is met
|
|
if (!stopCondition()) {
|
|
setTimeout(outerLoop, 0);
|
|
}
|
|
});
|
|
}
|
|
|
|
// Check whether n is prime, given a list of all primes < n
|
|
function isPrime(n, primes) {
|
|
for (const p of primes) {
|
|
if (n % p == 0) {
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
function findPrimesBlocking() {
|
|
let primes = [];
|
|
|
|
for (let n = 2; n < 1000000; n++) {
|
|
if (isPrime(n, primes)) {
|
|
primes.push(n);
|
|
}
|
|
if (n % 10000 == 0) {
|
|
let status = `Found ${primes.length} primes between 2 and ${n}`;
|
|
document.getElementById("display").textContent = status;
|
|
console.log(status);
|
|
}
|
|
}
|
|
document.getElementById("display").textContent =
|
|
`Found ${primes.length} primes between 2 and 1000000`;
|
|
}
|
|
|
|
function findPrimesNonBlocking() {
|
|
|
|
// Initialize loop variable and list of primes
|
|
let n = 2;
|
|
let primes = [];
|
|
|
|
// Yield every 1000 iterations and stop after 1000000
|
|
const stopCondition = () => n == 1000000;
|
|
const yieldCondition = () => n % 10000 == 0;
|
|
|
|
// Build the loop body to be passed to doUntil()
|
|
const loop = () => {
|
|
|
|
// Determine if n is prime
|
|
if (isPrime(n, primes)) {
|
|
primes.push(n);
|
|
}
|
|
|
|
// Increment n
|
|
n += 1;
|
|
|
|
// Update DOM if we're about to yield
|
|
if (yieldCondition()) {
|
|
let status = `Found ${primes.length} primes between 2 and ${n}`;
|
|
document.getElementById("display").textContent = status;
|
|
console.log(status);
|
|
}
|
|
};
|
|
|
|
// Execute
|
|
doUntil(loop, stopCondition, yieldCondition);
|
|
}
|