This repository has been archived by the owner on Dec 4, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
intCode.js
115 lines (103 loc) · 4.06 KB
/
intCode.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
class IntCode {
constructor(program) {
this._orig = program.split(',').map(Number);
this.reset();
this.opFunctions = new Map([
// Mapping of opcode and the functions that determine their results
// These functions return undefined or Integer
// If undefined, automatically increments by parameter count to next intruction.
// If Integer, determine thes jump index for the next instruction
[1, (param1, param2, param3, modes) => {
const value1 = this.getValue(param1, modes[0])
const value2 = this.getValue(param2, modes[1])
this.setValue(param3, modes[2], value1 + value2);
}],
[2, (param1, param2, param3, modes) => {
const value1 = this.getValue(param1, modes[0])
const value2 = this.getValue(param2, modes[1])
this.setValue(param3, modes[2], value1 * value2);
}],
[3, (param1, modes) => {
this.setValue(param1, modes[0], this.input);
this.input = undefined;
}],
[4, (param1, modes) => {
const value1 = this.getValue(param1, modes[0])
this.outputs.push(value1);
}],
[5, (param1, param2, modes) => {
const value1 = this.getValue(param1, modes[0])
const value2 = this.getValue(param2, modes[1])
if (value1 !== 0) {
return value2;
}
}],
[6, (param1, param2, modes) => {
const value1 = this.getValue(param1, modes[0])
const value2 = this.getValue(param2, modes[1])
if (value1 === 0) {
return value2;
}
}],
[7, (param1, param2, param3, modes) => {
const value1 = this.getValue(param1, modes[0])
const value2 = this.getValue(param2, modes[1])
this.setValue(param3, modes[2], value1 < value2 ? 1 : 0);
}],
[8, (param1, param2, param3, modes) => {
const value1 = this.getValue(param1, modes[0])
const value2 = this.getValue(param2, modes[1])
this.setValue(param3, modes[2], value1 === value2 ? 1 : 0);
}],
[9, (param1, modes) => {
this.relativeBase += this.getValue(param1, modes[0]);
}],
]);
return this;
}
get last() {
return this.outputs[this.outputs.length - 1]
}
getValue(param, mode) {
if (mode === 1) { //immidiate
return param || 0
}
if (mode === 2) { // relative
return this.program[this.relativeBase + param] || 0
}
return this.program[param] || 0 // position
}
setValue(param, mode, value){
this.program[mode === 2 ? this.relativeBase + param : param] = value;
}
clearOutputs(){
this.outputs = []
}
reset() {
this.program = this._orig;
this.outputs = [];
this.i = 0;
this.relativeBase = 0;
}
Run(input) {
this.input = input
while (true) {
const instruction = this.program[this.i].toString().split('');
const op = parseInt(instruction.slice(instruction.length - 2).join(''));
if (op === 99) {
return;
}
if (op === 3 && this.input === undefined) {
break;
}
const modes = instruction.slice(0, instruction.length - 2).reverse().map(Number)
const func = this.opFunctions.get(op);
var params = this.program.slice(this.i + 1, this.i + 1 + (func.length - 1))
// set the next instruction based on return of the function or automatically based on the number of parameters
this.i = (func(...params, modes) - 1) || (this.i + (func.length - 1));
this.i++
}
return this;
}
}
module.exports = IntCode;