main.js 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. function readAllSamples(cb) {
  2. require("fs").readFile('./input', 'utf8', (err, data) => {
  3. var samples = data.split("\n\n").map(l => {
  4. var args = l.match(/(\d+)/g);
  5. if (args)
  6. return new Sample(args);
  7. }).filter(i => !!i);
  8. cb(samples);
  9. });
  10. }
  11. function readProgram(cb) {
  12. require("fs").readFile('./testprogram', 'utf8', (err, data) => {
  13. cb(data.split("\n").filter(i => !!i).map(i => i.match(/(\d+)/g).map(i => parseInt(i))));
  14. });
  15. }
  16. var ops = {
  17. "addr": function(args, reg) { reg[args[3]] = reg[args[1]] +reg[args[2]]; },
  18. "addi": function(args, reg) { reg[args[3]] = reg[args[1]] +args[2]; },
  19. "mulr": function(args, reg) { reg[args[3]] = reg[args[1]] *reg[args[2]]; },
  20. "muli": function(args, reg) { reg[args[3]] = reg[args[1]] *args[2]; },
  21. "banr": function(args, reg) { reg[args[3]] = reg[args[1]] & reg[args[2]]; },
  22. "bani": function(args, reg) { reg[args[3]] = reg[args[1]] & args[2]; },
  23. "borr": function(args, reg) { reg[args[3]] = reg[args[1]] | reg[args[2]]; },
  24. "bori": function(args, reg) { reg[args[3]] = reg[args[1]] | args[2]; },
  25. "setr": function(args, reg) { reg[args[3]] = reg[args[1]] },
  26. "seti": function(args, reg) { reg[args[3]] = args[1] },
  27. "gtir": function(args, reg) { reg[args[3]] = args[1] > reg[args[2]] ? 1 : 0 },
  28. "gtri": function(args, reg) { reg[args[3]] = reg[args[1]] > args[2] ? 1 : 0 },
  29. "gtrr": function(args, reg) { reg[args[3]] = reg[args[1]] > reg[args[2]] ? 1 : 0 },
  30. "eqir": function(args, reg) { reg[args[3]] = args[1] == reg[args[2]] ? 1 : 0 },
  31. "eqri": function(args, reg) { reg[args[3]] = reg[args[1]] == args[2] ? 1 : 0 },
  32. "eqrr": function(args, reg) { reg[args[3]] = reg[args[1]] == reg[args[2]] ? 1 : 0 }
  33. };
  34. function Sample(args) {
  35. this.from = args.splice(0, 4).map(i => parseInt(i));
  36. this.args = args.splice(0, 4).map(i => parseInt(i));
  37. this.to = args.splice(0, 4).map(i => parseInt(i));
  38. }
  39. Sample.prototype.getNotPossibleOps = function() {
  40. var notPossibleOps = [];
  41. for (op in ops) {
  42. var reg = this.from.slice();
  43. ops[op](this.args, reg);
  44. var found = true;
  45. for (var i =0; i < reg.length && found; ++i)
  46. if (reg[i] !== this.to[i])
  47. found = false;
  48. if (!found)
  49. notPossibleOps.push(op);
  50. }
  51. return notPossibleOps;
  52. }
  53. function runSampleProgram(opCodeMap) {
  54. readProgram(instrs => {
  55. var reg = [ 0, 0, 0, 0 ];
  56. instrs.forEach(instr => opCodeMap[instr[0]](instr, reg));
  57. console.log("Registers: ", reg);
  58. });
  59. }
  60. function run() {
  61. readAllSamples(samples => {
  62. var sampleBehavingLikeThreeOrMoreOpcodes = 0,
  63. possibleOpCodes = [];
  64. for (var i in ops)
  65. possibleOpCodes.push(Object.keys(ops));
  66. samples.forEach(s => {
  67. var notPossibleOps = s.getNotPossibleOps();
  68. if (notPossibleOps.length <= possibleOpCodes.length -3)
  69. ++sampleBehavingLikeThreeOrMoreOpcodes;
  70. notPossibleOps.forEach(o => {
  71. var index = possibleOpCodes[s.args[0]].indexOf(o);
  72. if (index >= 0)
  73. possibleOpCodes[s.args[0]].splice(index, 1);
  74. });
  75. });
  76. console.log("Number of sample behaving like 3 or more opcodes: ", sampleBehavingLikeThreeOrMoreOpcodes);
  77. var found = true;
  78. while (found) {
  79. found = false;
  80. for (var i =0; i < possibleOpCodes.length; ++i)
  81. if (possibleOpCodes[i].length == 1)
  82. for (var j =0; j < possibleOpCodes.length; ++j)
  83. if (j != i && possibleOpCodes[j].indexOf(possibleOpCodes[i][0]) >= 0) {
  84. possibleOpCodes[j].splice(possibleOpCodes[j].indexOf(possibleOpCodes[i][0]), 1);
  85. found = true;
  86. }
  87. }
  88. var opCodeMap = possibleOpCodes.map(i => ops[i[0]]);
  89. runSampleProgram(opCodeMap);
  90. });
  91. }
  92. run();