Published
Edited
Dec 9, 2019
Insert cell
Insert cell
Insert cell
Insert cell
runProgram = function(program, inputs) {
let pos = 0;
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: // add
program[program[pos+3]] = a + b;
pos += 4;
break;
case 2: // multiply
program[program[pos+3]] = a * b;
pos += 4;
break;
case 3: // input
program[program[pos+1]] = inputs.shift();
pos += 2;
break;
case 4: // output
return a;
case 5: // jump-if-true
if (a !== 0) {
pos = b;
} else {
pos += 3;
}
break;
case 6: // jump-if-false
if (a === 0) {
pos = b;
} else {
pos += 3;
}
break;
case 7: // less than
program[program[pos+3]] = a < b ? 1 : 0;
pos += 4;
break;
case 8: // equals
program[program[pos+3]] = a === b ? 1 : 0;
pos += 4;
break;
default:
throw new Error(`Invalid Opcode: ${opcode}`);
}
opcode = program[pos];
}
return program;
}
Insert cell
tryPhases = function(phases) {
let out = 0;
let phase = phases.shift();
while (phase != null) {
out = runProgram(input.slice(0), [phase, out]);
phase = phases.shift();
}
return out;
}
Insert cell
function getAllPermutations(arr) {
if (arr.length === 1) {
return arr.slice(0);
}
const results = [];
for (let i = 0; i < arr.length; i++) {
const first = arr[i];
const remainder = arr.slice(0, i).concat(arr.slice(i + 1));
const innerPermutations = getAllPermutations(remainder);
innerPermutations.forEach((innerPerm) => {
results.push([first].concat(innerPerm));
});
}
return results;
}
Insert cell
{
let best = -1;
getAllPermutations([0,1,2,3,4]).forEach((phases) => {
let output = tryPhases(phases);
if (output > best) {
best = output;
}
});

return best;
}
Insert cell
Insert cell
Insert cell
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: // add
program[program[pos+3]] = a + b;
pos += 4;
break;
case 2: // multiply
program[program[pos+3]] = a * b;
pos += 4;
break;
case 3: // input
program[program[pos+1]] = inputs.shift();
pos += 2;
break;
case 4: // output
return [a, program.slice(0), pos + 2];
case 5: // jump-if-true
if (a !== 0) {
pos = b;
} else {
pos += 3;
}
break;
case 6: // jump-if-false
if (a === 0) {
pos = b;
} else {
pos += 3;
}
break;
case 7: // less than
program[program[pos+3]] = a < b ? 1 : 0;
pos += 4;
break;
case 8: // equals
program[program[pos+3]] = a === b ? 1 : 0;
pos += 4;
break;
default:
throw new Error(`Invalid Opcode: ${opcode}`);
}
opcode = program[pos];
}
return [null, program];
}
Insert cell
tryWithFeedback = function(phases) {
let amp = 0;
let out = 0;
let phase = phases.shift();
let answer;
const saveStates = new Map();
while (true) {
let program = input.slice(0);
let pointer = 0;
if (saveStates.has(amp)) {
[program, pointer] = saveStates.get(amp);
}
const inputs = [];
if (phase) {
inputs.push(phase);
}
inputs.push(out);
const [output, prog, point] = runInteruptable(program, inputs, pointer);
saveStates.set(amp, [prog, point]);
out = output;
phase = phases.shift();
if (amp === 4) {
console.log(output);
if (!output) {
return answer;
}
answer = output;
}
amp = (amp + 1) % 5;
}
}
Insert cell
{
let best = -1;
getAllPermutations([5,6,7,8,9]).forEach((phases) => {
let output = tryWithFeedback(phases);
if (output > best) {
best = output;
}
});

return best;
}
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more