Skip to content

Instantly share code, notes, and snippets.

@postspectacular
Created March 10, 2019 15:18
Show Gist options
  • Save postspectacular/3e14adf4633e57045814bad53b0e4182 to your computer and use it in GitHub Desktop.
Save postspectacular/3e14adf4633e57045814bad53b0e4182 to your computer and use it in GitHub Desktop.
Transducer based, branch-less 1D Wolfram automata (textmode)
const tx = require("@thi.ng/transducers");
const txb = require("@thi.ng/transducers-binary");
// ANSI clear screen esc seq
const CLEAR = "\x1b[2J\x1b[;H";
// CA dimensions
const WIDTH = 72;
const HEIGHT = 24;
// Wolfram rule ID
const RULE = 22;
// seed w/ 25% probability
const seed = () => [...txb.randomBits(0.25, WIDTH)];
// separate rule ID into bits
const parseRule = (id) => [...txb.bits(8, false, [id])];
// single evolution step
const evolve = (kernel, rule) => (src) =>
tx.transduce(
tx.comp(
// convolve curr generation w/ kernel
tx.convolve1d({
src,
kernel,
width: src.length,
wrap: true
}),
// apply rule
tx.map(tx.lookup1d(rule))
),
tx.push(),
tx.range(src.length)
);
// CA update as dynamically built transducer, wrapped in
// `tx.step()` for stepwise execution via setInterval (below)
const update = tx.step(
tx.comp(
// evolve current generation
tx.scan(
tx.reducer(
seed,
evolve(
tx.buildKernel1d([1, 2, 4], 3),
parseRule(RULE)
)
)
),
// transform new gen into ASCII art
tx.map((gen) => gen.map((x) => (x ? "#" : " ")).join("")),
// form sliding window of max `HEIGHT` last results
tx.slidingWindow(HEIGHT),
// join all lines into single string, prefix w/ clear screen cmd
tx.map((win) => CLEAR + win.join("\n")),
// print
tx.trace()
)
);
// kick off
setInterval(update, 16);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment