46 lines
1.6 KiB
JavaScript
46 lines
1.6 KiB
JavaScript
const alive = '#';
|
|
const dead = '.';
|
|
|
|
// ------------------------------------------------------------[ Bit banging ]--
|
|
const setBitAt = (val, idx) => BigInt(val) | (1n << BigInt(idx));
|
|
const clearBitAt = (val, idx) => BigInt(val) & ~(1n << BigInt(idx));
|
|
const getBitAt = val => idx => (BigInt(val) >> BigInt(idx)) & 1n;
|
|
const hasBitAt = val => idx => ((BigInt(val) >> BigInt(idx)) & 1n) === 1n;
|
|
|
|
// ----------------------------------------------------------------[ Utility ]--
|
|
const makeArr = n => Array(n).fill(0);
|
|
const reverse = x => Array.from(x).reduce((p, c) => [c, ...p], []);
|
|
const numToLine = width => int => {
|
|
const test = hasBitAt(int);
|
|
const looper = makeArr(width);
|
|
return reverse(looper.map((_, i) => test(i) ? alive : dead)).join('');
|
|
}
|
|
|
|
// -------------------------------------------------------------------[ Main ]--
|
|
const displayCA = (rule, width, lines, startIndex) => {
|
|
const result = [];
|
|
result.push(`Rule:${rule} Width:${width} Gen:${lines}\n`)
|
|
const ruleTest = hasBitAt(rule);
|
|
const lineLoop = makeArr(lines);
|
|
const looper = makeArr(width);
|
|
const pLine = numToLine(width);
|
|
|
|
let nTarget = setBitAt(0n, startIndex);
|
|
result.push(pLine(nTarget));
|
|
lineLoop.forEach(() => {
|
|
const bitTest = getBitAt(nTarget);
|
|
looper.forEach((e, i) => {
|
|
const l = bitTest(i === 0 ? width - 1 : i - 1);
|
|
const m = bitTest(i);
|
|
const r = bitTest(i === width - 1 ? 0 : i + 1);
|
|
nTarget = ruleTest(
|
|
parseInt([l, m, r].join(''), 2))
|
|
? setBitAt(nTarget, i)
|
|
: clearBitAt(nTarget, i);
|
|
});
|
|
result.push(pLine(nTarget));
|
|
});
|
|
return result.join('\n');
|
|
}
|
|
|
|
displayCA(90, 57, 31, 28);
|