Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // Advent of Code 2018
- // December 16, 2018
- // Author: Peter Jensen
- (function () {
- var fs = require("fs");
- var addr = 0;
- var addi = 1;
- var mulr = 2;
- var muli = 3;
- var banr = 4;
- var bani = 5;
- var borr = 6;
- var bori = 7;
- var setr = 8;
- var seti = 9;
- var gtir = 10;
- var gtri = 11;
- var gtrr = 12;
- var eqir = 13;
- var eqri = 14;
- var eqrr = 15;
- var opcodeMap = [
- addr, addi, mulr, muli, banr, bani, borr, bori, setr, seti, gtir, gtri, gtrr, eqir, eqri, eqrr
- ];
- function parseNumbers(numsStr) {
- var nums = numsStr.split(/[ ,]+/);
- for (var i = 0; i < nums.length; ++i) {
- nums[i] = parseInt(nums[i]);
- }
- return nums;
- }
- function readInput(fileName) {
- var input = fs["readFileSync"](fileName, "utf8");
- var lines = input.split(/[\r\n]+/);
- var index = 0;
- var samples = [];
- var program = [];
- while (index < lines.length) {
- var line = lines[index];
- if (line.substr(0, 6) == "Before") {
- var before = parseNumbers(line.substr(9, 10));
- var opcode = parseNumbers(lines[index+1]);
- var after = parseNumbers(lines[index+2].substr(9, 10));
- samples.push({before: before, opcode: opcode, after: after});
- index = index + 3;
- }
- else {
- program.push(parseNumbers(lines[index]));
- index++;
- }
- }
- return [samples, program];
- }
- function execute(opcode, input) {
- var output = input.slice(0);
- switch (opcodeMap[opcode[0]]) {
- case addr:
- var A = input[opcode[1]];
- var B = input[opcode[2]];
- output[opcode[3]] = A + B;
- break;
- case addi:
- var A = input[opcode[1]];
- var B = opcode[2];
- output[opcode[3]] = A + B;
- break;
- case mulr:
- var A = input[opcode[1]];
- var B = input[opcode[2]];
- output[opcode[3]] = A * B;
- break;
- case muli:
- var A = input[opcode[1]];
- var B = opcode[2];
- output[opcode[3]] = A * B;
- break;
- case banr:
- var A = input[opcode[1]];
- var B = input[opcode[2]];
- output[opcode[3]] = A & B;
- break;
- case bani:
- var A = input[opcode[1]];
- var B = opcode[2];
- output[opcode[3]] = A & B;
- break;
- case borr:
- var A = input[opcode[1]];
- var B = input[opcode[2]];
- output[opcode[3]] = A | B;
- break;
- case bori:
- var A = input[opcode[1]];
- var B = opcode[2];
- output[opcode[3]] = A | B;
- break;
- case setr:
- var A = input[opcode[1]];
- output[opcode[3]] = A;
- break;
- case seti:
- var A = opcode[1];
- output[opcode[3]] = A;
- break;
- case gtir:
- var A = opcode[1];
- var B = input[opcode[2]];
- output[opcode[3]] = A > B ? 1 : 0;
- break;
- case gtri:
- var A = input[opcode[1]];
- var B = opcode[2];
- output[opcode[3]] = A > B ? 1 : 0;
- break;
- case gtrr:
- var A = input[opcode[1]];
- var B = input[opcode[2]];
- output[opcode[3]] = A > B ? 1 : 0;
- break;
- case eqir:
- var A = opcode[1];
- var B = input[opcode[2]];
- output[opcode[3]] = A == B ? 1 : 0;
- break;
- case eqri:
- var A = input[opcode[1]];
- var B = opcode[2];
- output[opcode[3]] = A == B ? 1 : 0;
- break;
- case eqrr:
- var A = input[opcode[1]];
- var B = input[opcode[2]];
- output[opcode[3]] = A == B ? 1 : 0;
- break;
- }
- return output;
- }
- function numOpcodes(sample) {
- var n = 0;
- var opcode = sample.opcode.slice(0);
- for (var opIndex = 0; opIndex < opcodeMap.length; ++opIndex) {
- opcode[0] = opcodeMap[opIndex];
- var v = execute(opcode, sample.before);
- if (v[opcode[3]] == sample.after[opcode[3]]) {
- n++;
- }
- }
- return n;
- }
- function getPossibilities(sample) {
- var p = [];
- var opcode = sample.opcode.slice(0);
- for (var opIndex = 0; opIndex < opcodeMap.length; ++opIndex) {
- opcode[0] = opcodeMap[opIndex];
- var v = execute(opcode, sample.before);
- if (v[opcode[3]] == sample.after[opcode[3]]) {
- p.push(opcode[0]);
- }
- }
- return p;
- }
- function filterPossibilities(possibilities, p) {
- return possibilities.filter(function (val) {return p.indexOf(val) != -1;})
- }
- function findOpcodePossibilities(op, samples) {
- var possibilities = [];
- for (var i = 0; i < samples.length; ++i) {
- if (samples[i].opcode[0] == op) {
- var p = getPossibilities(samples[i]);
- if (possibilities.length == 0) {
- possibilities = p.slice(0);
- }
- else {
- possibilities = filterPossibilities(possibilities, p);
- }
- }
- }
- return possibilities;
- }
- function removeFrom(value, pMap) {
- var removed = false;
- for (var i = 0; i < pMap.length; ++i) {
- if (pMap[i].length > 1) {
- var e = pMap[i].indexOf(value);
- if (e != -1) {
- pMap[i].splice(e, 1);
- removed = true;
- }
- }
- }
- return removed;
- }
- function trimMap(pMap) {
- var trimming = true;
- while (trimming) {
- trimming = false;
- for (var i = 0; i < pMap.length; ++i) {
- if (pMap[i].length == 1) {
- if (removeFrom(pMap[i][0], pMap)) {
- trimming = true;
- }
- }
- }
- }
- }
- function updateOpcodeMap(pMap) {
- for (var i = 0; i < pMap.length; ++i) {
- opcodeMap[i] = pMap[i][0];
- }
- }
- function executeProgram(program, registers) {
- for (var i = 0; i < program.length; ++i) {
- registers = execute(program[i], registers);
- }
- return registers;
- }
- function main() {
- var input = readInput(process["argv"][2]);
- var samples = input[0];
- var program = input[1];
- // console.log("Samples: " + samples.length);
- // console.log("Program: ");
- // console.log(program);
- var threeOrMore = 0;
- for (var i = 0; i < samples.length; ++i) {
- var n = numOpcodes(samples[i]);
- if (n >= 3) {
- threeOrMore++;
- }
- }
- console.log("Three or More: " + threeOrMore);
- var pMap = [];
- for (var op = 0; op < opcodeMap.length; ++op) {
- var p = findOpcodePossibilities(op, samples);
- pMap.push(p);
- }
- // console.log("Before trimming:");
- // console.log(pMap);
- trimMap(pMap);
- // console.log("After trimming:");
- // console.log(pMap);
- updateOpcodeMap(pMap);
- // console.log("Executing Program:");
- var registers = executeProgram(program, [0, 0, 0, 0]);
- // console.log(registers);
- console.log("Register 0 after program execution: " + registers[0]);
- }
- function test() {
- var sample = {before: [3, 2, 1, 1], opcode: [9, 2, 1, 2], after: [3, 2, 2, 1]}
- console.log(numOpcodes(sample));
- }
- main();
- //test();
- })();
Add Comment
Please, Sign In to add comment