DISK 12 / RULE 110
a row of cells, each on or off, and a rule that says what each cell is in the next row from itself and its two neighbours: eight cases, eight answers. this one, rule 110, is simple enough to fit in a byte and has been proved able to compute anything any computer can
function setup(ctx, W, H) {
var k = { rule: 110, mid: 0, noise: 0 }
/*TWEAK*/
var n = 256, rows = []
var row = new Uint8Array(n)
if (k.noise) { for (var i = 0; i < n; i++) row[i] = Math.random() < 0.5 ? 1 : 0 } else row[k.mid ? n / 2 : n - 2] = 1
for (var r = 0; r < n; r++) rows.push(new Uint8Array(n))
rows[n - 1] = row
var c = document.createElement('canvas')
c.width = n
c.height = n
var cx = c.getContext('2d')
return { k: k, n: n, rows: rows, c: c, cx: cx, img: cx.createImageData(n, n) }
}
function update(state, t, W, H) {
var n = state.n, rows = state.rows, last = rows[n - 1], next = new Uint8Array(n), rule = state.k.rule
for (var i = 0; i < n; i++) {
var idx = (last[(i + n - 1) % n] << 2) | (last[i] << 1) | last[(i + 1) % n]
next[i] = (rule >> idx) & 1 ? 1 + idx : 0
}
for (var j = 0; j < n; j++) next[j] = next[j] ? 1 : 0
rows.shift()
rows.push(next)
}
function render(ctx, state, t, W, H) {
var n = state.n, rows = state.rows, d = state.img.data
for (var y = 0; y < n; y++) {
var r = rows[y]
for (var x = 0; x < n; x++) {
var i = (y * n + x) * 4, on = r[x]
var age = y / n
d[i] = on ? 240 * age + 15 : 12; d[i + 1] = on ? 120 + 100 * (1 - age) : 14; d[i + 2] = on ? 200 : 24; d[i + 3] = 255
}
}
state.cx.putImageData(state.img, 0, 0)
ctx.imageSmoothingEnabled = false
ctx.drawImage(state.c, 0, 0, W, H)
}