Skip to content

Instantly share code, notes, and snippets.

@bmershon
Last active December 6, 2016 04:55
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/2e68f575ab3d2396918c5b9c791a5f8d to your computer and use it in GitHub Desktop.
Save bmershon/2e68f575ab3d2396918c5b9c791a5f8d to your computer and use it in GitHub Desktop.
Sequence Q III
height: 2000
border: no
license: MIT
(function() {
var Hofstadter;
// Hofstadter's chaotic function Q
// computed using a dynamic programming
function q(n) {
var A = [],
i;
A[0] = 0
A[1] = 1;
A[2] = 1;
for (i = 3; i <= n; i++) {
A[i] = A[i - A[i - 1]] + A[i - A[i - 2]];
}
return A[n];
}
Hofstadter = {};
Hofstadter.function = {};
Hofstadter.function.Q = q;
d3.Hofstadter = Hofstadter;
})();
<!DOCTYPE html>
<meta charset="utf-8">
<style>
.node circle {
fill: #000;
}
.node text {
font: 11px sans-serif;
}
.node--internal text {
text-shadow: 0 1px 0 #fff, 0 -1px 0 #fff, 1px 0 0 #fff, -1px 0 0 #fff;
}
.link {
fill: none;
stroke-width: 2px;
stroke-opacity: 1;
}
</style>
<svg width="960" height="2000"></svg>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script src="https://d3js.org/d3-scale-chromatic.v1.min.js"></script>
<script src="hofstadter.js"></script>
<script>
var svg = d3.select("svg"),
node, link,
width = +svg.attr("width"),
height = +svg.attr("height"),
padding = 50;
var tree, root,
N = 300,
color, y, max;
svg = svg
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(" + padding / 2 + ",0)");
y = d3.scaleLinear().domain([1, N]).range([height, 0]);
color = d3.interpolateRdBu;
sequence = d3.range(N).map(function(d, i) {
return d3.Hofstadter.function.Q(i);
});
data = sequence.slice(1).map(function(d, i) {
var parent = (i === 0) ? "" : d;
return {name: "" + (i + 1), parent: "" + parent};
});
max = d3.max(sequence, function(d, i) {
return Math.abs(d - i);
});
root = d3.stratify()
.id(function(d) { return d.name; })
.parentId(function(d) { return d.parent; })
(data);
tree = d3.tree()
.size([width - padding, height - padding])
(root);
link = svg.selectAll(".link")
.data(root.descendants().slice(1))
.enter().append("path")
.attr("class", "link")
.attr("stroke", colorize)
.attr("d", spline);
function colorize(d) {
return color(Math.abs(+d.data.name - +d.data.parent) / max);
}
function spline(d) {
return "M" + d.x + "," + y(+d.data.name)
+ "C" + (d.x + d.parent.x) / 2 + "," + y(+d.data.name)
+ " " + (d.x + d.parent.x) / 2 + "," + y(+d.parent.data.name)
+ " " + d.parent.x + "," + y(+d.parent.data.name);
}
node = svg.selectAll(".node")
.data(root.descendants())
.enter().append("g")
.attr("class", "node")
.attr("transform", function(d) { return "translate(" + d.x + "," + y(+d.data.name) + ")"; });
node.append("circle")
.attr("r", 2);
</script>
importScripts('https://d3js.org/d3-array.v1.min.js');
importScripts('https://d3js.org/d3-hierarchy.v1.min.js');
importScripts('hofstadter.js');
onmessage = function(event) {
var sequence = d3.range(event.data.N).map(function(d, i) {
postMessage({type: "tick", progress: i / (100 * 3)});
return d3.Hofstadter.function.Q(i);
});
var structure = sequence.slice(1).map(function(d, i) {
postMessage({type: "tick", progress: i / (100 * 3)});
var parent = (i === 0) ? "" : d;
return {name: "" + (i + 1), parent: "" + parent};
});
var max = d3.max(sequence, function(d, i) {
postMessage({type: "tick", progress: i / (100 * 3)});
return Math.abs(d - i);
});
var root = d3.stratify()
.id(function(d) { return d.name; })
.parentId(function(d) { return d.parent; })
(structure);
postMessage({type: "end", root: root});
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment