runInteruptable = function(program, inputs, pointer = 0) {
let pos = pointer;
let opcode = program[pos];
while (opcode !== 99) {
const aMode = /1\d{2}$/.test(opcode) ? 1 : 0;
const bMode = /1\d{3}$/.test(opcode) ? 1 : 0;
const cMode = /1\d{4}$/.test(opcode) ? 1 : 0;
const a = aMode ? program[pos+1] : program[program[pos+1]];
const b = bMode ? program[pos+2] : program[program[pos+2]];
const c = cMode ? program[pos+3] : program[program[pos+3]];
opcode = parseInt(`${opcode}`.slice(-1), 10);
switch (opcode) {
case 1:
program[program[pos+3]] = a + b;
pos += 4;
break;
case 2:
program[program[pos+3]] = a * b;
pos += 4;
break;
case 3:
program[program[pos+1]] = inputs.shift();
pos += 2;
break;
case 4:
return [a, program.slice(0), pos + 2];
case 5:
if (a !== 0) {
pos = b;
} else {
pos += 3;
}
break;
case 6:
if (a === 0) {
pos = b;
} else {
pos += 3;
}
break;
case 7:
program[program[pos+3]] = a < b ? 1 : 0;
pos += 4;
break;
case 8:
program[program[pos+3]] = a === b ? 1 : 0;
pos += 4;
break;
default:
throw new Error(`Invalid Opcode: ${opcode}`);
}
opcode = program[pos];
}
return [null, program];
}