Guest User

Untitled

a guest
Dec 16th, 2018
92
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.75 KB | None | 0 0
  1. // Advent of Code 2018
  2. // December 16, 2018
  3. // Author: Peter Jensen
  4.  
  5. (function () {
  6. var fs = require("fs");
  7.  
  8. var addr = 0;
  9. var addi = 1;
  10. var mulr = 2;
  11. var muli = 3;
  12. var banr = 4;
  13. var bani = 5;
  14. var borr = 6;
  15. var bori = 7;
  16. var setr = 8;
  17. var seti = 9;
  18. var gtir = 10;
  19. var gtri = 11;
  20. var gtrr = 12;
  21. var eqir = 13;
  22. var eqri = 14;
  23. var eqrr = 15;
  24.  
  25. var opcodeMap = [
  26. addr, addi, mulr, muli, banr, bani, borr, bori, setr, seti, gtir, gtri, gtrr, eqir, eqri, eqrr
  27. ];
  28.  
  29. function parseNumbers(numsStr) {
  30. var nums = numsStr.split(/[ ,]+/);
  31. for (var i = 0; i < nums.length; ++i) {
  32. nums[i] = parseInt(nums[i]);
  33. }
  34. return nums;
  35. }
  36.  
  37. function readInput(fileName) {
  38. var input = fs["readFileSync"](fileName, "utf8");
  39. var lines = input.split(/[\r\n]+/);
  40. var index = 0;
  41. var samples = [];
  42. var program = [];
  43. while (index < lines.length) {
  44. var line = lines[index];
  45. if (line.substr(0, 6) == "Before") {
  46. var before = parseNumbers(line.substr(9, 10));
  47. var opcode = parseNumbers(lines[index+1]);
  48. var after = parseNumbers(lines[index+2].substr(9, 10));
  49. samples.push({before: before, opcode: opcode, after: after});
  50. index = index + 3;
  51. }
  52. else {
  53. program.push(parseNumbers(lines[index]));
  54. index++;
  55. }
  56. }
  57. return [samples, program];
  58. }
  59.  
  60. function execute(opcode, input) {
  61. var output = input.slice(0);
  62. switch (opcodeMap[opcode[0]]) {
  63. case addr:
  64. var A = input[opcode[1]];
  65. var B = input[opcode[2]];
  66. output[opcode[3]] = A + B;
  67. break;
  68. case addi:
  69. var A = input[opcode[1]];
  70. var B = opcode[2];
  71. output[opcode[3]] = A + B;
  72. break;
  73. case mulr:
  74. var A = input[opcode[1]];
  75. var B = input[opcode[2]];
  76. output[opcode[3]] = A * B;
  77. break;
  78. case muli:
  79. var A = input[opcode[1]];
  80. var B = opcode[2];
  81. output[opcode[3]] = A * B;
  82. break;
  83. case banr:
  84. var A = input[opcode[1]];
  85. var B = input[opcode[2]];
  86. output[opcode[3]] = A & B;
  87. break;
  88. case bani:
  89. var A = input[opcode[1]];
  90. var B = opcode[2];
  91. output[opcode[3]] = A & B;
  92. break;
  93. case borr:
  94. var A = input[opcode[1]];
  95. var B = input[opcode[2]];
  96. output[opcode[3]] = A | B;
  97. break;
  98. case bori:
  99. var A = input[opcode[1]];
  100. var B = opcode[2];
  101. output[opcode[3]] = A | B;
  102. break;
  103. case setr:
  104. var A = input[opcode[1]];
  105. output[opcode[3]] = A;
  106. break;
  107. case seti:
  108. var A = opcode[1];
  109. output[opcode[3]] = A;
  110. break;
  111. case gtir:
  112. var A = opcode[1];
  113. var B = input[opcode[2]];
  114. output[opcode[3]] = A > B ? 1 : 0;
  115. break;
  116. case gtri:
  117. var A = input[opcode[1]];
  118. var B = opcode[2];
  119. output[opcode[3]] = A > B ? 1 : 0;
  120. break;
  121. case gtrr:
  122. var A = input[opcode[1]];
  123. var B = input[opcode[2]];
  124. output[opcode[3]] = A > B ? 1 : 0;
  125. break;
  126. case eqir:
  127. var A = opcode[1];
  128. var B = input[opcode[2]];
  129. output[opcode[3]] = A == B ? 1 : 0;
  130. break;
  131. case eqri:
  132. var A = input[opcode[1]];
  133. var B = opcode[2];
  134. output[opcode[3]] = A == B ? 1 : 0;
  135. break;
  136. case eqrr:
  137. var A = input[opcode[1]];
  138. var B = input[opcode[2]];
  139. output[opcode[3]] = A == B ? 1 : 0;
  140. break;
  141. }
  142. return output;
  143. }
  144.  
  145. function numOpcodes(sample) {
  146. var n = 0;
  147. var opcode = sample.opcode.slice(0);
  148. for (var opIndex = 0; opIndex < opcodeMap.length; ++opIndex) {
  149. opcode[0] = opcodeMap[opIndex];
  150. var v = execute(opcode, sample.before);
  151. if (v[opcode[3]] == sample.after[opcode[3]]) {
  152. n++;
  153. }
  154. }
  155. return n;
  156. }
  157.  
  158. function getPossibilities(sample) {
  159. var p = [];
  160. var opcode = sample.opcode.slice(0);
  161. for (var opIndex = 0; opIndex < opcodeMap.length; ++opIndex) {
  162. opcode[0] = opcodeMap[opIndex];
  163. var v = execute(opcode, sample.before);
  164. if (v[opcode[3]] == sample.after[opcode[3]]) {
  165. p.push(opcode[0]);
  166. }
  167. }
  168. return p;
  169. }
  170.  
  171. function filterPossibilities(possibilities, p) {
  172. return possibilities.filter(function (val) {return p.indexOf(val) != -1;})
  173. }
  174.  
  175. function findOpcodePossibilities(op, samples) {
  176. var possibilities = [];
  177. for (var i = 0; i < samples.length; ++i) {
  178. if (samples[i].opcode[0] == op) {
  179. var p = getPossibilities(samples[i]);
  180. if (possibilities.length == 0) {
  181. possibilities = p.slice(0);
  182. }
  183. else {
  184. possibilities = filterPossibilities(possibilities, p);
  185. }
  186. }
  187. }
  188. return possibilities;
  189. }
  190.  
  191. function removeFrom(value, pMap) {
  192. var removed = false;
  193. for (var i = 0; i < pMap.length; ++i) {
  194. if (pMap[i].length > 1) {
  195. var e = pMap[i].indexOf(value);
  196. if (e != -1) {
  197. pMap[i].splice(e, 1);
  198. removed = true;
  199. }
  200. }
  201. }
  202. return removed;
  203. }
  204.  
  205. function trimMap(pMap) {
  206. var trimming = true;
  207. while (trimming) {
  208. trimming = false;
  209. for (var i = 0; i < pMap.length; ++i) {
  210. if (pMap[i].length == 1) {
  211. if (removeFrom(pMap[i][0], pMap)) {
  212. trimming = true;
  213. }
  214. }
  215. }
  216. }
  217. }
  218.  
  219. function updateOpcodeMap(pMap) {
  220. for (var i = 0; i < pMap.length; ++i) {
  221. opcodeMap[i] = pMap[i][0];
  222. }
  223. }
  224.  
  225. function executeProgram(program, registers) {
  226. for (var i = 0; i < program.length; ++i) {
  227. registers = execute(program[i], registers);
  228. }
  229. return registers;
  230. }
  231.  
  232. function main() {
  233. var input = readInput(process["argv"][2]);
  234. var samples = input[0];
  235. var program = input[1];
  236. // console.log("Samples: " + samples.length);
  237. // console.log("Program: ");
  238. // console.log(program);
  239. var threeOrMore = 0;
  240. for (var i = 0; i < samples.length; ++i) {
  241. var n = numOpcodes(samples[i]);
  242. if (n >= 3) {
  243. threeOrMore++;
  244. }
  245. }
  246. console.log("Three or More: " + threeOrMore);
  247. var pMap = [];
  248. for (var op = 0; op < opcodeMap.length; ++op) {
  249. var p = findOpcodePossibilities(op, samples);
  250. pMap.push(p);
  251. }
  252. // console.log("Before trimming:");
  253. // console.log(pMap);
  254. trimMap(pMap);
  255. // console.log("After trimming:");
  256. // console.log(pMap);
  257. updateOpcodeMap(pMap);
  258. // console.log("Executing Program:");
  259. var registers = executeProgram(program, [0, 0, 0, 0]);
  260. // console.log(registers);
  261. console.log("Register 0 after program execution: " + registers[0]);
  262. }
  263.  
  264. function test() {
  265. var sample = {before: [3, 2, 1, 1], opcode: [9, 2, 1, 2], after: [3, 2, 2, 1]}
  266. console.log(numOpcodes(sample));
  267. }
  268.  
  269. main();
  270. //test();
  271. })();
Add Comment
Please, Sign In to add comment