Skip to content

Instantly share code, notes, and snippets.

@towc
Last active December 16, 2018 09:59
Show Gist options
  • Select an option

  • Save towc/0ccd9b917368ae1b7d9d546ab1c7d5db to your computer and use it in GitHub Desktop.

Select an option

Save towc/0ccd9b917368ae1b7d9d546ab1c7d5db to your computer and use it in GitHub Desktop.
const fs = require('fs');
const [OP, A, B, C] = [0, 1, 2, 3];
const samples = fs.readFileSync('input', 'utf-8')
.split('\n\n')
.map(cluster => cluster.split('\n'))
.filter(lines => lines.length === 3)
.map(lines => {
return ({
before: eval(lines[0].split(':')[1]),
after: eval(lines[2].split(':')[1]),
code: lines[1].split(' ').map(Number),
})
});
const addr = (regs, code) => regs[code[C]] = regs[code[A]] + regs[code[B]];
const addi = (regs, code) => regs[code[C]] = regs[code[A]] + code[B];
const mulr = (regs, code) => regs[code[C]] = regs[code[A]] * regs[code[B]];
const muli = (regs, code) => regs[code[C]] = regs[code[A]] * code[B];
const banr = (regs, code) => regs[code[C]] = regs[code[A]] & regs[code[B]];
const bani = (regs, code) => regs[code[C]] = regs[code[A]] & code[B];
const borr = (regs, code) => regs[code[C]] = regs[code[A]] | regs[code[B]];
const bori = (regs, code) => regs[code[C]] = regs[code[A]] | code[B];
const setr = (regs, code) => regs[code[C]] = regs[code[A]];
const seti = (regs, code) => regs[code[C]] = code[A];
const gtir = (regs, code) => regs[code[C]] = +(code[A] > regs[code[B]]);
const gtri = (regs, code) => regs[code[C]] = +(regs[code[A]] > code[B]);
const gtrr = (regs, code) => regs[code[C]] = +(regs[code[A]] > regs[code[B]]);
const eqir = (regs, code) => regs[code[C]] = +(code[A] === regs[code[B]]);
const eqri = (regs, code) => regs[code[C]] = +(regs[code[A]] === code[B]);
const eqrr = (regs, code) => regs[code[C]] = +(regs[code[A]] === regs[code[B]]);
const allOps = [
addr, addi,
mulr, muli,
banr, bani,
borr, bori,
setr, seti,
gtir, gtri, gtrr,
eqir, eqri, eqrr
];
const getMatches = sample =>
allOps.filter((op) => {
const toModify = [...sample.before];
op(toModify, sample.code);
return registersMatch(sample.after, toModify);
})
const registersMatch = (a, b) =>
a[0] === b[0] &&
a[1] === b[1] &&
a[2] === b[2] &&
a[3] === b[3];
const opcodes = allOps.map((_, i) => ({
num: i,
ops: [...allOps],
}));
samples.forEach((sample) => {
const matches = getMatches(sample);
const op = opcodes[sample.code[OP]];
op.ops = op.ops.filter(fn => matches.includes(fn));
});
let sec = 0;
let found = opcodes.filter(op => op.ops.length === 1);
let notFound = opcodes.filter(op => op.ops.length > 1);
while(found.length < opcodes.length && ++sec < 1000) {
for(let i = 0; i < notFound.length; ++i) {
const op = notFound[i];
op.ops = op.ops.filter(fn => !found.some(foundOp => foundOp.ops.includes(fn)));
if (op.ops.length === 1) {
found.push(op)
notFound.splice(i, 1);
--i;
}
}
}
const ops = opcodes.map(op => op.ops[0]);
const program = fs.readFileSync('input', 'utf-8')
.split('\n\n')
.pop()
.trim()
.split('\n')
.map(l => l.split(' ').map(Number));
let regs = [0, 0, 0, 0];
program.forEach(line => ops[line[OP]](regs, line));
console.log(regs);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment