|
|
@@ -0,0 +1,101 @@
|
|
|
+
|
|
|
+function readAllSamples(cb) {
|
|
|
+ require("fs").readFile('./input', 'utf8', (err, data) => {
|
|
|
+ var samples = data.split("\n\n").map(l => {
|
|
|
+ var args = l.match(/(\d+)/g);
|
|
|
+ if (args)
|
|
|
+ return new Sample(args);
|
|
|
+ }).filter(i => !!i);
|
|
|
+ cb(samples);
|
|
|
+ });
|
|
|
+}
|
|
|
+
|
|
|
+function readProgram(cb) {
|
|
|
+ require("fs").readFile('./testprogram', 'utf8', (err, data) => {
|
|
|
+ cb(data.split("\n").filter(i => !!i).map(i => i.match(/(\d+)/g).map(i => parseInt(i))));
|
|
|
+ });
|
|
|
+}
|
|
|
+
|
|
|
+var ops = {
|
|
|
+ "addr": function(args, reg) { reg[args[3]] = reg[args[1]] +reg[args[2]]; },
|
|
|
+ "addi": function(args, reg) { reg[args[3]] = reg[args[1]] +args[2]; },
|
|
|
+ "mulr": function(args, reg) { reg[args[3]] = reg[args[1]] *reg[args[2]]; },
|
|
|
+ "muli": function(args, reg) { reg[args[3]] = reg[args[1]] *args[2]; },
|
|
|
+ "banr": function(args, reg) { reg[args[3]] = reg[args[1]] & reg[args[2]]; },
|
|
|
+ "bani": function(args, reg) { reg[args[3]] = reg[args[1]] & args[2]; },
|
|
|
+ "borr": function(args, reg) { reg[args[3]] = reg[args[1]] | reg[args[2]]; },
|
|
|
+ "bori": function(args, reg) { reg[args[3]] = reg[args[1]] | args[2]; },
|
|
|
+ "setr": function(args, reg) { reg[args[3]] = reg[args[1]] },
|
|
|
+ "seti": function(args, reg) { reg[args[3]] = args[1] },
|
|
|
+ "gtir": function(args, reg) { reg[args[3]] = args[1] > reg[args[2]] ? 1 : 0 },
|
|
|
+ "gtri": function(args, reg) { reg[args[3]] = reg[args[1]] > args[2] ? 1 : 0 },
|
|
|
+ "gtrr": function(args, reg) { reg[args[3]] = reg[args[1]] > reg[args[2]] ? 1 : 0 },
|
|
|
+ "eqir": function(args, reg) { reg[args[3]] = args[1] == reg[args[2]] ? 1 : 0 },
|
|
|
+ "eqri": function(args, reg) { reg[args[3]] = reg[args[1]] == args[2] ? 1 : 0 },
|
|
|
+ "eqrr": function(args, reg) { reg[args[3]] = reg[args[1]] == reg[args[2]] ? 1 : 0 }
|
|
|
+};
|
|
|
+
|
|
|
+function Sample(args) {
|
|
|
+ this.from = args.splice(0, 4).map(i => parseInt(i));
|
|
|
+ this.args = args.splice(0, 4).map(i => parseInt(i));
|
|
|
+ this.to = args.splice(0, 4).map(i => parseInt(i));
|
|
|
+}
|
|
|
+
|
|
|
+Sample.prototype.getNotPossibleOps = function() {
|
|
|
+ var notPossibleOps = [];
|
|
|
+ for (op in ops) {
|
|
|
+ var reg = this.from.slice();
|
|
|
+ ops[op](this.args, reg);
|
|
|
+ var found = true;
|
|
|
+ for (var i =0; i < reg.length && found; ++i)
|
|
|
+ if (reg[i] !== this.to[i])
|
|
|
+ found = false;
|
|
|
+ if (!found)
|
|
|
+ notPossibleOps.push(op);
|
|
|
+ }
|
|
|
+ return notPossibleOps;
|
|
|
+}
|
|
|
+
|
|
|
+function runSampleProgram(opCodeMap) {
|
|
|
+ readProgram(instrs => {
|
|
|
+ var reg = [ 0, 0, 0, 0 ];
|
|
|
+ instrs.forEach(instr => opCodeMap[instr[0]](instr, reg));
|
|
|
+ console.log("Registers: ", reg);
|
|
|
+ });
|
|
|
+}
|
|
|
+
|
|
|
+function run() {
|
|
|
+ readAllSamples(samples => {
|
|
|
+ var sampleBehavingLikeThreeOrMoreOpcodes = 0,
|
|
|
+ possibleOpCodes = [];
|
|
|
+ for (var i in ops)
|
|
|
+ possibleOpCodes.push(Object.keys(ops));
|
|
|
+ samples.forEach(s => {
|
|
|
+ var notPossibleOps = s.getNotPossibleOps();
|
|
|
+ if (notPossibleOps.length <= possibleOpCodes.length -3)
|
|
|
+ ++sampleBehavingLikeThreeOrMoreOpcodes;
|
|
|
+ notPossibleOps.forEach(o => {
|
|
|
+ var index = possibleOpCodes[s.args[0]].indexOf(o);
|
|
|
+ if (index >= 0)
|
|
|
+ possibleOpCodes[s.args[0]].splice(index, 1);
|
|
|
+ });
|
|
|
+ });
|
|
|
+ console.log("Number of sample behaving like 3 or more opcodes: ", sampleBehavingLikeThreeOrMoreOpcodes);
|
|
|
+ var found = true;
|
|
|
+ while (found) {
|
|
|
+ found = false;
|
|
|
+ for (var i =0; i < possibleOpCodes.length; ++i)
|
|
|
+ if (possibleOpCodes[i].length == 1)
|
|
|
+ for (var j =0; j < possibleOpCodes.length; ++j)
|
|
|
+ if (j != i && possibleOpCodes[j].indexOf(possibleOpCodes[i][0]) >= 0) {
|
|
|
+ possibleOpCodes[j].splice(possibleOpCodes[j].indexOf(possibleOpCodes[i][0]), 1);
|
|
|
+ found = true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ var opCodeMap = possibleOpCodes.map(i => ops[i[0]]);
|
|
|
+ runSampleProgram(opCodeMap);
|
|
|
+ });
|
|
|
+}
|
|
|
+
|
|
|
+run();
|
|
|
+
|