Published
Edited
Dec 12, 2019
1 star
Insert cell
Insert cell
Insert cell
Insert cell
md`**${Object.entries(panels(0)).length}**`
Insert cell
Insert cell
program = puzzleInput.split(",")
Insert cell
panels = function (start) {
let painted = { },
pos = {x:0, y:0},
dir = 0,
col = 0;
let dir2mv = {
0 : {x: 0, y: 1},
1 : {x: 1, y: 0},
2 : {x: 0, y: -1},
3 : {x: -1, y: 0}
};
//painted[[pos.x,pos.y]] = start;
let output = intcomp(program, [start]);
while (output.opcode !== "99") {
painted[[pos.x,pos.y]] = output.value[0];
dir = (dir + 3 + 2 * output.value[1] + 4) % 4;
pos.x += dir2mv[dir].x;
pos.y += dir2mv[dir].y;
col = painted[[pos.x,pos.y]] || 0;
output = intcomp(output.mem, [col], output.pc, 0, output.relbase);
}
return painted
}
Insert cell
function intcomp (program, input = [], pc = 0, memstart, relbase = 0) {
let outputLog = [];
let inputs = input;//[input];
//if (pc == 0) inputs.push(phase); // better have explicit init option
let mem = program.map(Number);
let start = memstart || 0;
let op, opcode, modes, x, p1, p2, p3, offset,
output, i, step, ampOut=[], wait = false;
let mode2calcAddress = {
0: i => mem[i]+start,
1: i => i,
2: i => mem[i]+start+relbase
};
for (i = pc; i < program.length; i += step) {
op = mem[i].toString().padStart(6, 0);
output = i.toString().padStart(4, 0) + ": " + op + " ";
opcode = op.slice(-2);
modes = op.slice(0, -2).split('').reverse();
if ( !modes.every( m => m === '0' || m === '1' || m === '2') )
{
outputLog.push (output + 'unknown mode: ' + modes);
break;
}
if (opcode == '99') break
p1 = mem[mode2calcAddress[modes[0]](i+1)] || 0; //memory needs to initialized to 0s, not documented
p2 = mem[mode2calcAddress[modes[1]](i+2)] || 0;
p3 = mode2calcAddress[modes[2]](i+3) || 0; // p3 is always address directly, no lookup
step = 4;
switch (opcode) {
case '01':
mem[p3] = p1 + p2;
output += [p1, p2, p3, mem[p3]].join();
break;
case '02':
mem[p3] = p1 * p2;
output += [p1, p2, p3, mem[p3]].join();
break;
case '03': //input
if (inputs.length == 0) { wait = true; break }; //wait for next input
step = 2;
offset = mode2calcAddress[modes[0]](i+1); // no indirection
mem[offset] = inputs.pop();
output += 'input ' + mem[offset] + " to " + offset;
break;
case '04': //output
step = 2;
output += (p1 != 0 ? "### " : "ok! ") + mode2calcAddress[modes[0]](i+1) + ' output: ' + p1;
ampOut.push(p1);
break;
case '05':
step = 3;
if (p1 != 0) { i = p2 - step; }
output += p1 + ' != 0: jumpT ' + (p2);
break;
case '06':
step = 3;
if (p1 == 0) { i = p2 - step; }
output += 'jumpF ' + (i + step);
break;
case '07':
x = 0;
if (p1 < p2) { x = 1 }
mem[p3] = x;
output += p1 + ' less ' + p2 + ": " + mem[p3];
break;
case '08':
x = 0;
if (p1 == p2) { x = 1 }
mem[p3] = x;
output += p1 + ' == ' + p2 + ' into ' + p3;
break;
case '09':
step = 2;
relbase += p1;
output += 'relative base: ' + relbase;
break;
default:
output += 'unknown opcode: ' + opcode;
break;
}
if (wait) break;
outputLog.push(output);
}
return {log: outputLog, value: ampOut, opcode: opcode, mem: mem, pc: i, relbase: relbase}
}
Insert cell
Insert cell
Insert cell
identifier = panels(1)
Insert cell
whitePanels = Object.entries(identifier).filter(p => p[1] == 1)
Insert cell
xys = [whitePanels.map(p => p[0].split(",")[0]).map(Number), whitePanels.map(p => p[0].split(",")[1]).map(Number)]
Insert cell
xDim = [Math.min(...xys[0]), Math.max(...xys[0])]
Insert cell
yDim = [Math.min(...xys[1]), Math.max(...xys[1])]
Insert cell
idsign = {
let w = xDim[1] - xDim[0];
let h = yDim[1] - yDim[0];
let sign = Array(h+1+2).fill(Array(w+1+2).fill(0));
return sign.map((row, y) => row.map((v, x) => identifier[ [x-1+xDim[0], h-y+1+yDim[0] ] ]));
}
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more