Skip to content

Instantly share code, notes, and snippets.

@bmershon
Last active February 28, 2017 02:41
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 bmershon/8bed98a4633d86403e1ca56165cda6da to your computer and use it in GitHub Desktop.
Save bmershon/8bed98a4633d86403e1ca56165cda6da to your computer and use it in GitHub Desktop.
Sieve of Eratosthenes
scrolling: yes
border: no
license: MIT
height: 960
<!DOCTYPE html>
<meta charset="utf-8">
<script src="https://d3js.org/d3.v4.min.js"></script>
<body>
<p id="time"></p>
</body>
<script>
// From Mathematics to Generic Programming, p. 27.
var worker = new Worker("./worker.js");
// Compute prime less than 100,000.
worker.postMessage({ n: 100000});
worker.onmessage = function(event) {
switch (event.data.type) {
case "end": return ended(event.data);
}
};
// Render computed primes when the Web Worker is done.
function ended(data) {
d3.select("#time")
.style("margin-left", "5px")
.style("font-size", "14px")
.style("color", "#aaa")
.style("font-family", "helvetica")
.html("Sifted " + d3.format(",")(data.values.length) + " primes in " + data.elapsed + " ms");
d3.select("body").append("p")
.datum(data.values)
.html(function(d) { return d.join(" "); })
.style("margin", "0 auto")
.style("font-size", "18px")
.style("font-family", "helvetica")
.style("line-height", "1.4em")
.style("width", "720px");
}
</script>
onmessage = function(event) {
var n = event.data.n,
startTime = Date.now(),
endTime;
var computedPrimes = primes(n);
endTime = Date.now();
postMessage({
type: "end",
values: computedPrimes,
elapsed: endTime - startTime
});
}
// Returns an array containing the primes less than or equal to n.
function primes(n) {
var sieve = new Array(Math.ceil(index(n)));
sieve.fill(true);
sift(sieve);
return sieve.reduce(function(accumulator, current, i, array) {
if (current) accumulator.push(value(i));
return accumulator;
}, [2]);
}
function sift(sieve) {
var i = 0,
squaredIndex = 3,
factor = 3;
while (squaredIndex < sieve.length) {
if (sieve[i]) {
markSieve(sieve, squaredIndex, value(i));
} // else all multiples of this factor have been crossed out
i++;
squaredIndex += factor;
factor += 2; // e.g., 3 -> 5 -> 7 -> 9
squaredIndex += factor; // squredIndex += factor(i) + factor(i + 1)
}
return sieve;
}
// Mark boolean sieve false for all multiples of the
// given factor.
function markSieve(sieve, begin, factor) {
var i, n;
for (i = begin, n = sieve.length; i < n - factor; i += factor) {
sieve[i] = false;
}
}
// Returns the value of a number in the sieve containing only
// odd numbers and starting at 3.
function value(i) {
return i + i + 3;
}
// Returns the index for a value in the sieve containing only
// odd numbers and starting at 3.
function index(v) {
return (v - 3) / 2;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment