| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101 |
- 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();
|