function intcomp (program, phase, input = 0, pc = 0) {
let outputLog = [];
let inputs = [input];
if (pc == 0) inputs.push(phase);
let mem = program.map(Number);
let op, opcode, modes, x, p1, p2, p3, output, i, step, ampOut, wait = false;
for (i = pc; i < program.length; i += step) {
op = mem[i].toString().padStart(6, 0);
output = i.toString().padStart(4, 0) + ": " + op + " ";
opcode = op.slice(-2);
modes = op.slice(0, -2).split('').reverse();
if ( !modes.every( m => m == '0' || m == '1' ) )
{
outputLog.push (output + 'unknown mode: ' + modes);
break;
}
if (opcode == '99') break
p1 = modes[0] == '0' ? mem[mem[i+1]] : mem[i+1];
p2 = modes[1] == '0' ? mem[mem[i+2]] : mem[i+2];
p3 = modes[2] == '1' ? mem[mem[i+3]] : mem[i+3];
step = 4;
switch (opcode) {
case '01':
mem[p3] = p1 + p2;
output += [p1, p2, p3, mem[p3]].join();
break;
case '02':
mem[p3] = p1 * p2;
output += [p1, p2, p3, mem[p3]].join();
break;
case '03':
if (inputs.length == 0) { wait = true; break };
step = 2;
mem[mem[i+1]] = inputs.pop();
output += 'input ' + mem[mem[i+1]];
break;
case '04':
step = 2;
output += (p1 != 0 ? "### " : "ok! ") + 'output: ' + p1;
ampOut = p1;
break;
case '05':
step = 3;
if (p1 != 0) { i = p2 - step; }
output += 'jumpT ' + (i + step);
break;
case '06':
step = 3;
if (p1 == 0) { i = p2 - step; }
output += 'jumpF ' + (i + step);
break;
case '07':
x = 0;
if (p1 < p2) { x = 1 }
mem[p3] = x;
output += 'less ' + x;
break;
case '08':
x = 0;
if (p1 == p2) { x = 1 }
mem[p3] = x;
output += 'eq ' + x;
break;
default:
output += 'unknown opcode: ' + opcode;
break;
}
if (wait) break;
outputLog.push(output);
}
return {log: outputLog, value: ampOut, opcode: opcode, mem: mem, pc: i}
}