-
Notifications
You must be signed in to change notification settings - Fork 0
/
lib_intcode.js
executable file
·102 lines (86 loc) · 3.89 KB
/
lib_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
/**
* intcode processor
*
* @param {string} input program source code
* @param {int[]} user_input
* @param {function} callback function in case of missing input
* @returns {string} return value
*/
let aoc_intcode = {
process: function(input, user_input = [], callback = {}) {
let program = input.split(",").map(x => parseInt(x));
let pointer = 0;
let output = [];
this.relative_base = 0;
while (program[pointer] !== 99) {
const opcode = program[pointer].toString().padStart(5, "0");
const op_parts = opcode.split("").map(x => parseInt(x));
// ATTENTION parameter order is reversed
// first: op_parts[2]
// second: op_parts[1]
// third: op_parts[0]
switch (op_parts[4]) {
case 1:
program[this.get_pointer(program, pointer+3, op_parts[0])] = program[this.get_pointer(program, pointer+1, op_parts[2])] + program[this.get_pointer(program, pointer+2, op_parts[1])];
pointer += 4;
break;
case 2:
program[this.get_pointer(program, pointer+3, op_parts[0])] = program[this.get_pointer(program, pointer+1, op_parts[2])] * program[this.get_pointer(program, pointer+2, op_parts[1])];
pointer += 4;
break;
case 3:
if (user_input.length === 0) {
if (typeof callback === 'function') {
let new_input = callback(output);
if (typeof new_input === 'undefined')
return output.join(',');
user_input.push(new_input);
output = [];
}
else
return output.join(',');
}
program[this.get_pointer(program, pointer+1, op_parts[2])] = user_input.shift();
pointer += 2;
break;
case 4:
output.push(program[this.get_pointer(program, pointer+1, op_parts[2])]);
pointer += 2;
break;
case 5:
if (program[this.get_pointer(program, pointer+1, op_parts[2])] > 0)
pointer = program[this.get_pointer(program, pointer+2, op_parts[1])];
else
pointer += 3;
break;
case 6:
if (program[this.get_pointer(program, pointer+1, op_parts[2])] === 0)
pointer = program[this.get_pointer(program, pointer+2, op_parts[1])];
else
pointer += 3;
break;
case 7:
program[this.get_pointer(program, pointer+3, op_parts[0])] = (program[this.get_pointer(program, pointer+1, op_parts[2])] < program[this.get_pointer(program, pointer+2, op_parts[1])]) ? 1 : 0;
pointer += 4;
break;
case 8:
program[this.get_pointer(program, pointer+3, op_parts[0])] = (program[this.get_pointer(program, pointer+1, op_parts[2])] === program[this.get_pointer(program, pointer+2, op_parts[1])]) ? 1 : 0;
pointer += 4;
break;
case 9:
this.relative_base += program[this.get_pointer(program, pointer+1, op_parts[2])];
pointer += 2;
break;
}
}
return output.join(',');
},
get_pointer: function(program, pointer, mode) {
if (mode === 2)
return program[pointer] + this.relative_base;
else if (mode === 1)
return pointer;
else
return program[pointer];
}
};