Skip to content

Commit a01e187

Browse files
committed
Adds in optimized computer
1 parent c6278a4 commit a01e187

File tree

2 files changed

+83
-24
lines changed

2 files changed

+83
-24
lines changed

2019/23/input.js

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
1-
const input = [
2-
3,62,1001,62,11,10,109,2247,105,1,0,769,738,1707,1991,1216,2026,1738,1872,1119,602,1913,1643,571,633,1150,944,1548,1775,1583,845,1482,1045,1676,2152,2121,1453,2057,2216,670,701,1389,2185,1513,1839,1424,911,1008,1808,1612,1086,1346,810,977,1284,1960,2088,1315,1185,1249,880,0,0,0,0,0,0,0,0,0,0,0,0,3,64,1008,64,-1,62,1006,62,88,1006,61,170,1106,0,73,3,65,20101,0,64,1,21002,66,1,2,21102,1,105,0,1106,0,436,1201,1,-1,64,1007,64,0,62,1005,62,73,7,64,67,62,1006,62,73,1002,64,2,133,1,133,68,133,101,0,0,62,1001,133,1,140,8,0,65,63,2,63,62,62,1005,62,73,1002,64,2,161,1,161,68,161,1102,1,1,0,1001,161,1,169,1002,65,1,0,1102,1,1,61,1102,0,1,63,7,63,67,62,1006,62,203,1002,63,2,194,1,68,194,194,1006,0,73,1001,63,1,63,1106,0,178,21102,1,210,0,106,0,69,1201,1,0,70,1102,1,0,63,7,63,71,62,1006,62,250,1002,63,2,234,1,72,234,234,4,0,101,1,234,240,4,0,4,70,1001,63,1,63,1105,1,218,1106,0,73,109,4,21101,0,0,-3,21102,0,1,-2,20207,-2,67,-1,1206,-1,293,1202,-2,2,283,101,1,283,283,1,68,283,283,22001,0,-3,-3,21201,-2,1,-2,1106,0,263,22102,1,-3,-3,109,-4,2106,0,0,109,4,21101,0,1,-3,21102,0,1,-2,20207,-2,67,-1,1206,-1,342,1202,-2,2,332,101,1,332,332,1,68,332,332,22002,0,-3,-3,21201,-2,1,-2,1105,1,312,21202,-3,1,-3,109,-4,2106,0,0,109,1,101,1,68,359,20102,1,0,1,101,3,68,367,20101,0,0,2,21101,0,376,0,1106,0,436,21201,1,0,0,109,-1,2105,1,0,1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768,65536,131072,262144,524288,1048576,2097152,4194304,8388608,16777216,33554432,67108864,134217728,268435456,536870912,1073741824,2147483648,4294967296,8589934592,17179869184,34359738368,68719476736,137438953472,274877906944,549755813888,1099511627776,2199023255552,4398046511104,8796093022208,17592186044416,35184372088832,70368744177664,140737488355328,281474976710656,562949953421312,1125899906842624,109,8,21202,-6,10,-5,22207,-7,-5,-5,1205,-5,521,21102,1,0,-4,21101,0,0,-3,21102,1,51,-2,21201,-2,-1,-2,1201,-2,385,470,21002,0,1,-1,21202,-3,2,-3,22207,-7,-1,-5,1205,-5,496,21201,-3,1,-3,22102,-1,-1,-5,22201,-7,-5,-7,22207,-3,-6,-5,1205,-5,515,22102,-1,-6,-5,22201,-3,-5,-3,22201,-1,-4,-4,1205,-2,461,1105,1,547,21102,1,-1,-4,21202,-6,-1,-6,21207,-7,0,-5,1205,-5,547,22201,-7,-6,-7,21201,-4,1,-4,1106,0,529,22101,0,-4,-7,109,-8,2106,0,0,109,1,101,1,68,563,21002,0,1,0,109,-1,2105,1,0,1101,92077,0,66,1101,1,0,67,1101,0,598,68,1101,0,556,69,1101,1,0,71,1101,0,600,72,1106,0,73,1,23,16,11677,1102,1,68881,66,1102,1,1,67,1102,629,1,68,1101,556,0,69,1101,1,0,71,1102,1,631,72,1106,0,73,1,293,30,96994,1101,0,50497,66,1101,0,4,67,1101,0,660,68,1101,0,302,69,1101,0,1,71,1101,0,668,72,1105,1,73,0,0,0,0,0,0,0,0,21,220244,1101,0,39971,66,1102,1,1,67,1102,697,1,68,1102,1,556,69,1101,0,1,71,1101,0,699,72,1105,1,73,1,-87,14,29938,1101,0,59557,66,1102,1,1,67,1102,728,1,68,1102,556,1,69,1102,4,1,71,1101,0,730,72,1105,1,73,1,2,13,50497,13,100994,7,91571,7,183142,1102,33893,1,66,1101,0,1,67,1102,1,765,68,1102,1,556,69,1102,1,1,71,1101,0,767,72,1106,0,73,1,-7640,21,330366,1101,0,67789,66,1101,1,0,67,1102,796,1,68,1101,556,0,69,1102,6,1,71,1102,1,798,72,1106,0,73,1,24414,15,173378,19,164146,19,246219,41,67987,41,135974,41,203961,1102,1,67987,66,1101,0,3,67,1102,837,1,68,1101,0,302,69,1101,0,1,71,1101,0,843,72,1105,1,73,0,0,0,0,0,0,6,49261,1102,1,82073,66,1102,1,3,67,1102,872,1,68,1102,1,302,69,1102,1,1,71,1101,878,0,72,1106,0,73,0,0,0,0,0,0,6,98522,1102,1,61751,66,1102,1,1,67,1102,1,907,68,1102,1,556,69,1102,1,1,71,1101,909,0,72,1105,1,73,1,125,36,390332,1102,1,8753,66,1102,2,1,67,1101,938,0,68,1101,0,302,69,1101,0,1,71,1102,942,1,72,1105,1,73,0,0,0,0,39,89966,1102,1,86689,66,1102,1,2,67,1102,1,971,68,1102,1,302,69,1101,1,0,71,1102,975,1,72,1105,1,73,0,0,0,0,6,147783,1102,1,53759,66,1102,1,1,67,1102,1004,1,68,1101,0,556,69,1101,1,0,71,1102,1,1006,72,1105,1,73,1,29,40,650657,1102,97583,1,66,1102,1,4,67,1101,0,1035,68,1101,0,302,69,1101,1,0,71,1102,1043,1,72,1105,1,73,0,0,0,0,0,0,0,0,7,366284,1101,0,55061,66,1101,6,0,67,1101,0,1072,68,1102,1,253,69,1102,1,1,71,1101,0,1084,72,1106,0,73,0,0,0,0,0,0,0,0,0,0,0,0,23,96386,1102,1,44983,66,1101,0,2,67,1102,1113,1,68,1101,0,302,69,1101,1,0,71,1101,1117,0,72,1106,0,73,0,0,0,0,11,148726,1102,29363,1,66,1102,1,1,67,1101,1146,0,68,1101,0,556,69,1101,1,0,71,1101,1148,0,72,1106,0,73,1,82,13,201988,1101,0,14969,66,1102,1,3,67,1102,1177,1,68,1102,302,1,69,1101,1,0,71,1101,0,1183,72,1105,1,73,0,0,0,0,0,0,19,82073,1101,66587,0,66,1102,1,1,67,1102,1212,1,68,1101,556,0,69,1101,1,0,71,1102,1214,1,72,1105,1,73,1,59,40,92951,1102,38867,1,66,1101,2,0,67,1102,1,1243,68,1102,1,302,69,1101,0,1,71,1101,0,1247,72,1106,0,73,0,0,0,0,35,17506,1102,1,84659,66,1102,1,3,67,1102,1276,1,68,1101,302,0,69,1101,0,1,71,1101,1282,0,72,1105,1,73,0,0,0,0,0,0,21,165183,1101,0,61253,66,1101,0,1,67,1101,0,1311,68,1102,556,1,69,1102,1,1,71,1101,0,1313,72,1105,1,73,1,-157,40,371804,1102,4591,1,66,1102,1,1,67,1101,0,1342,68,1102,556,1,69,1101,0,1,71,1102,1,1344,72,1105,1,73,1,619,16,23354,1101,0,92951,66,1101,0,7,67,1101,0,1373,68,1102,1,302,69,1102,1,1,71,1102,1,1387,72,1106,0,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,197044,1101,48497,0,66,1101,0,3,67,1101,1416,0,68,1101,302,0,69,1102,1,1,71,1102,1,1422,72,1106,0,73,0,0,0,0,0,0,21,275305,1102,1,16361,66,1101,1,0,67,1101,1451,0,68,1101,556,0,69,1101,0,0,71,1101,0,1453,72,1106,0,73,1,1422,1101,0,55381,66,1102,1,1,67,1101,1480,0,68,1102,556,1,69,1102,1,0,71,1102,1,1482,72,1105,1,73,1,1152,1101,0,91967,66,1101,1,0,67,1101,0,1509,68,1101,556,0,69,1101,1,0,71,1102,1,1511,72,1105,1,73,1,37,40,464755,1101,100591,0,66,1102,1,3,67,1101,0,1540,68,1101,0,302,69,1102,1,1,71,1101,0,1546,72,1105,1,73,0,0,0,0,0,0,21,55061,1101,0,11677,66,1101,0,3,67,1102,1,1575,68,1101,0,302,69,1102,1,1,71,1101,1581,0,72,1105,1,73,0,0,0,0,0,0,21,110122,1101,0,991,66,1102,1,1,67,1102,1,1610,68,1101,556,0,69,1102,1,0,71,1101,0,1612,72,1106,0,73,1,1947,1102,81973,1,66,1101,0,1,67,1102,1639,1,68,1102,1,556,69,1102,1,1,71,1102,1641,1,72,1105,1,73,1,967,32,201182,1101,0,74363,66,1101,2,0,67,1101,1670,0,68,1101,302,0,69,1102,1,1,71,1102,1,1674,72,1105,1,73,0,0,0,0,23,48193,1102,1,96259,66,1102,1,1,67,1102,1,1703,68,1102,1,556,69,1102,1,1,71,1102,1705,1,72,1106,0,73,1,4,48,253977,1102,11779,1,66,1101,0,1,67,1102,1734,1,68,1102,556,1,69,1102,1,1,71,1101,0,1736,72,1106,0,73,1,31,13,151491,1101,49261,0,66,1102,1,4,67,1102,1,1765,68,1101,253,0,69,1101,0,1,71,1102,1,1773,72,1105,1,73,0,0,0,0,0,0,0,0,45,98179,1101,38861,0,66,1101,0,1,67,1102,1802,1,68,1102,556,1,69,1101,2,0,71,1101,0,1804,72,1105,1,73,1,10,36,195166,7,549426,1101,0,48751,66,1102,1,1,67,1102,1,1835,68,1102,1,556,69,1102,1,1,71,1102,1837,1,72,1106,0,73,1,160,7,457855,1102,1,74873,66,1102,1,1,67,1102,1866,1,68,1101,0,556,69,1101,2,0,71,1101,1868,0,72,1106,0,73,1,601,40,185902,14,14969,1101,0,91571,66,1101,6,0,67,1102,1899,1,68,1102,1,302,69,1102,1,1,71,1102,1911,1,72,1105,1,73,0,0,0,0,0,0,0,0,0,0,0,0,45,196358,1101,66179,0,66,1102,1,1,67,1102,1940,1,68,1101,556,0,69,1101,0,9,71,1102,1,1942,72,1106,0,73,1,1,40,278853,4,77734,35,8753,39,44983,11,74363,16,35031,30,48497,32,301773,14,44907,1102,17959,1,66,1101,1,0,67,1102,1,1987,68,1101,0,556,69,1102,1,1,71,1102,1,1989,72,1105,1,73,1,136,32,100591,1102,23557,1,66,1101,1,0,67,1101,2018,0,68,1101,0,556,69,1101,0,3,71,1102,2020,1,72,1106,0,73,1,5,36,97583,36,292749,7,274713,1101,42179,0,66,1101,1,0,67,1101,2053,0,68,1102,556,1,69,1101,0,1,71,1102,1,2055,72,1106,0,73,1,-2,48,84659,1101,0,43991,66,1102,1,1,67,1102,2084,1,68,1102,556,1,69,1101,1,0,71,1102,2086,1,72,1105,1,73,1,11,40,557706,1102,1,98179,66,1101,0,2,67,1102,2115,1,68,1102,351,1,69,1101,1,0,71,1102,1,2119,72,1106,0,73,0,0,0,0,255,67789,1101,34897,0,66,1102,1,1,67,1102,2148,1,68,1101,556,0,69,1102,1,1,71,1101,0,2150,72,1106,0,73,1,58,30,145491,1101,48193,0,66,1102,1,2,67,1102,1,2179,68,1101,302,0,69,1101,1,0,71,1101,2183,0,72,1106,0,73,0,0,0,0,15,86689,1101,68771,0,66,1101,0,1,67,1102,2212,1,68,1102,1,556,69,1101,1,0,71,1102,2214,1,72,1105,1,73,1,11717,4,38867,1101,18787,0,66,1101,0,1,67,1101,2243,0,68,1102,1,556,69,1102,1,1,71,1102,1,2245,72,1105,1,73,1,3469,48,169318
3-
]
1+
const path = require('path');
2+
const fs = require('fs');
3+
4+
const input = fs
5+
.readFileSync(path.join(__dirname, 'input.txt'), 'utf8')
6+
.toString()
7+
.trim()
8+
.split(',')
9+
.map(v => parseInt(v, 10));
410

511
module.exports = {
612
input,

2019/23/intcode-computer.js renamed to 2019/23/intcode-computer-optimized.js

Lines changed: 74 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
const readline = require('readline');
2-
const { green, cyan } = require('colors');
3-
41
const ADD = '01'; // Add
52
const MUL = '02'; // Multiply
63
const INP = '03'; // Input
@@ -38,6 +35,8 @@ class Computer {
3835
this.replenish_input = replenish_input;
3936
this.outputs = [];
4037

38+
this.parseOpTime = 0;
39+
4140
this.OPS = {
4241
[ADD]: {
4342
name: ADD,
@@ -63,7 +62,7 @@ class Computer {
6362
name: INP,
6463
realName: 'INP',
6564
params: 1,
66-
fn: a => {
65+
fn: (a) => {
6766
this.memory[a] = this.inputs.shift();
6867
if (this.replenish_input !== undefined) {
6968
this.inputs.push(this.replenish_input);
@@ -76,14 +75,14 @@ class Computer {
7675
name: OUT,
7776
realName: 'OUT',
7877
params: 1,
79-
fn: a => this.output(a),
78+
fn: (a) => this.output(a),
8079
},
8180

8281
[ARB]: {
8382
name: ARB,
8483
realName: 'ARB',
8584
params: 1,
86-
fn: a => (this.relative_base += a),
85+
fn: (a) => (this.relative_base += a),
8786
},
8887

8988
[STP]: {
@@ -142,6 +141,32 @@ class Computer {
142141
},
143142
};
144143

144+
const ops_list = Object.values(this.OPS);
145+
const max_params = Math.max(...ops_list.map((v) => v.params));
146+
const shared_modes = Array(max_params).fill('0');
147+
148+
/**
149+
* Use shared arrays for `modes` and `value`.
150+
*
151+
* We can share a single array for `modes` since we know
152+
* the number of params for an op, meaning if an op has
153+
* 2 params, we can determine the modes for the 1st and
154+
* 2nd values, and the 3rd value will just be "junk" data
155+
* we'll ignore.
156+
*
157+
* The `values` for the ops need to be unique though, since
158+
* we spread out the values into our function call. Also
159+
* good to note that another optimization is we have hard-coded
160+
* fn calls for the number of params. `fn(...[1, 2])` is
161+
* slower than `fn(1, 2)`, so we code for 0 - 3 params, with
162+
* a default case of a spread. Similar libraries like lodash
163+
* do this.
164+
*/
165+
for (let op of ops_list) {
166+
op.modes = shared_modes;
167+
op.values = Array(op.params).fill(0);
168+
}
169+
145170
this.halted = false;
146171
}
147172

@@ -173,23 +198,25 @@ class Computer {
173198

174199
let full_op = temp_op.padStart(op.params + 2, '0');
175200

176-
let modes = [];
177-
178201
// "Parameter modes are single digits, one per parameter, read **right-to-left** from the opcode"
179202
for (let i = op.params - 1; i >= 0; i--) {
180-
modes.push(full_op[i]);
203+
// [0,1,2,3,4,5]
204+
// ^ ops.params = 6
205+
// 5 -> 0 # |(5 - 6 + 1)| = | 0| = 0
206+
// 4 -> 1 # |(4 - 6 + 1)| = |-1| = 1
207+
// 3 -> 2 # |(3 - 6 + 1)| = |-2| = 2
208+
// 2 -> 3 # |(2 - 6 + 1)| = |-3| = 3
209+
// 1 -> 4 # |(1 - 6 + 1)| = |-4| = 4
210+
// 0 -> 5 # |(0 - 6 + 1)| = |-5| = 5
211+
op.modes[Math.abs(i - op.params + 1)] = full_op[i];
181212
}
182213

183-
return {
184-
...op,
185-
modes,
186-
};
214+
return op;
187215
}
188216

189-
runOp({ modes, fn, jumps, write }) {
217+
runOp({ modes, values, params, fn, jumps, write }) {
190218
this.pointer++;
191-
let values = [];
192-
for (let i = 0; i < modes.length; i++) {
219+
for (let i = 0; i < params; i++) {
193220
let mode = modes[i];
194221
let value = this.memory[this.pointer + i];
195222

@@ -227,7 +254,7 @@ class Computer {
227254
*
228255
* Now, if I were to re-map the pointer'd `@` symbols, I'd get
229256
*
230-
* @3 = @1 + 2
257+
* 7 = 9 + 2
231258
*
232259
* But _that isn't what we want!_ Namely, it doesn't make sense
233260
* to set the _literal_ number 7 equal to some addition operation.
@@ -259,7 +286,7 @@ class Computer {
259286
* - I am running an op that does _not_ write to memory
260287
* - Or if I am not at the last parameter in the op
261288
*/
262-
const can_switch_to_position = !write || i < modes.length - 1;
289+
const can_switch_to_position = !write || i < params - 1;
263290

264291
if (can_switch_to_position && mode === POSITION_MODE) {
265292
value = this.memory[value];
@@ -283,14 +310,40 @@ class Computer {
283310
value = 0;
284311
}
285312

286-
values.push(value);
313+
values[i] = value;
287314
}
288315

289316
// If result is `true`, we moved the pointer
290-
let result = fn(...values);
317+
let result;
318+
319+
/**
320+
* Always spreading args is slow, so we can create a few base cases
321+
* (actually all our base cases) to speed up these function calls.
322+
* We still have a default case if for some reason we have an op
323+
* with more than 3 params (we don't), so this code is future proof,
324+
* but this change offers a ~2x speed improvement.
325+
*/
326+
switch (params) {
327+
case 0:
328+
result = fn();
329+
break;
330+
case 1:
331+
result = fn(values[0]);
332+
break;
333+
case 2:
334+
result = fn(values[0], values[1]);
335+
break;
336+
case 3:
337+
result = fn(values[0], values[1], values[2]);
338+
break;
339+
default:
340+
// Spreads are slow, so use direct branches for known number of params
341+
result = fn(...values);
342+
break;
343+
}
291344

292345
if (!jumps || (jumps && !result)) {
293-
this.pointer += modes.length;
346+
this.pointer += params;
294347
}
295348
}
296349

0 commit comments

Comments
 (0)