Computer.js 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. const Stack = require("./Stack");
  2. /**
  3. * An Intcode Computer for the Advent of Code 2019 challenge
  4. *
  5. * @author Apis Necros
  6. */
  7. module.exports = class Computer {
  8. constructor(stack) {
  9. this.stack = new Stack(stack);
  10. this.OPCODES = {
  11. ADD: 1,
  12. MULTIPLY: 2,
  13. HALT: 99,
  14. };
  15. }
  16. /**
  17. * Run the computer
  18. *
  19. * Runs opcodes on the stack until either the a HALT command is
  20. * encountered, or an error is thrown.
  21. * @returns {void}
  22. */
  23. Run() {
  24. // eslint-disable-next-line no-empty
  25. while (this.Execute(this.stack.Get()) === true) { }
  26. }
  27. /**
  28. * Execute a call using the provided opcode
  29. *
  30. * @param {number} opcode A opcode to execute
  31. * @returns {boolean} False if the opcode was HALT, otherwise true
  32. */
  33. Execute(opcode) {
  34. // console.log(`DEBUG: opcode: ${opcode}`)
  35. let status = true;
  36. switch (opcode) {
  37. case this.OPCODES.ADD: {
  38. const operandLeft = this.stack.Next().GetUsingStackValue();
  39. const operandRight = this.stack.Next().GetUsingStackValue();
  40. const position = this.stack.Next().Get();
  41. this.Operation_Add(operandLeft, operandRight, position);
  42. break;
  43. }
  44. case this.OPCODES.MULTIPLY: {
  45. const operandLeft = this.stack.Next().GetUsingStackValue();
  46. const operandRight = this.stack.Next().GetUsingStackValue();
  47. const position = this.stack.Next().Get();
  48. this.Operation_Multiply(operandLeft, operandRight, position);
  49. break;
  50. }
  51. case this.OPCODES.HALT:
  52. status = false;
  53. break;
  54. default:
  55. throw Error(`Opcode ${opcode} not found`);
  56. }
  57. this.stack.Next();
  58. return status;
  59. }
  60. /**
  61. * Execute the Add opcode
  62. *
  63. * Adds two numbers and stores the result at the provided position
  64. * on the stack.
  65. *
  66. * @param {number} operandLeft The first operand
  67. * @param {number} operandRight The second operand
  68. * @param {number} outputPosition The position on the stack to place the result
  69. * @returns {void}
  70. */
  71. Operation_Add(operandLeft, operandRight, outputPosition) {
  72. const newValue = operandLeft + operandRight;
  73. this.stack.Put(outputPosition, newValue);
  74. }
  75. /**
  76. * Execute the Multiply opcode
  77. *
  78. * Multiplies two numbers and stores the result at the provided
  79. * position on the stack.
  80. *
  81. * @param {number} operandLeft The first operand
  82. * @param {number} operandRight The second operand
  83. * @param {number} outputPosition The position on the stack to place the result
  84. * @returns {void}
  85. */
  86. Operation_Multiply(operandLeft, operandRight, outputPosition) {
  87. const newValue = operandLeft * operandRight;
  88. this.stack.Put(outputPosition, newValue);
  89. }
  90. /**
  91. * Outputs the computer's stack to the console
  92. * @returns {void}
  93. */
  94. DumpMemory() {
  95. console.log(this.stack.Dump());
  96. }
  97. };