Last active
December 16, 2018 09:59
-
-
Save towc/0ccd9b917368ae1b7d9d546ab1c7d5db to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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