well part 1 was straightforward... is the solution for part 2 to run it in reverse?

This commit is contained in:
David 2024-12-17 21:28:29 -05:00
parent be9e7619cd
commit 6a472c73e8

117
17/index.ts Normal file
View File

@ -0,0 +1,117 @@
import fs from "node:fs";
import { printTime, now, toNum } from "../util";
const test = false;
const data = fs.readFileSync(
test ? "./inputs/testinput" : "./inputs/input",
"utf8"
);
let timer = now.instant();
let computer = data
.split("\n")
.slice(0, -1)
.reduce(
(state, line, i) => {
switch (i) {
case 0:
state.A = toNum(line.split(": ")[1]);
break;
case 1:
state.B = toNum(line.split(": ")[1]);
break;
case 2:
state.C = toNum(line.split(": ")[1]);
break;
case 3:
break;
case 4:
state.Program = line.split(": ")[1].split(",").map(toNum);
}
return state;
},
{ A: 0, B: 0, C: 0, Program: [], Output: [] } as {
A: number;
B: number;
C: number;
Program: number[];
Output: number[];
}
);
const comboOperand = (computer, instructionPointer: number) => {
switch (computer.Program[instructionPointer + 1]) {
case 0:
case 1:
case 2:
case 3:
return computer.Program[instructionPointer + 1];
case 4:
return computer.A;
case 5:
return computer.B;
case 6:
return computer.C;
case 7:
throw "invalid!";
}
};
let instructionPointer = 0;
while (instructionPointer < computer.Program.length) {
let instruction = computer.Program[instructionPointer];
switch (instruction) {
case 0: // adv: A/(2^combo-operand) => A
computer.A = Math.trunc(
computer.A / 2 ** comboOperand(computer, instructionPointer)
);
instructionPointer += 2;
break;
case 1: // bxl: XOR(B, literal=operand) => B
computer.B = computer.B ^ computer.Program[instructionPointer + 1];
instructionPointer += 2;
break;
case 2: // bst: combo-operand % 8 => B
computer.B = comboOperand(computer, instructionPointer) % 8;
instructionPointer += 2;
break;
case 3: // jnz: jump to literal operand if non-zero register A
if (computer.A !== 0) {
instructionPointer = computer.Program[instructionPointer + 1];
} else {
instructionPointer += 2;
}
break;
case 4: // bxc: XOR(B, C) => B (consumes and ignores operand)
computer.B = computer.B ^ computer.C;
instructionPointer += 2;
break;
case 5: // out: combo-operand => Output
computer.Output.push(comboOperand(computer, instructionPointer) % 8);
instructionPointer += 2;
break;
case 6: // bdv: A/(2^combo-operand) => B
computer.B = Math.trunc(
computer.A / 2 ** comboOperand(computer, instructionPointer)
);
instructionPointer += 2;
break;
case 7: // cdv: A/(2^combo-operand) => C
computer.C = Math.trunc(
computer.A / 2 ** comboOperand(computer, instructionPointer)
);
instructionPointer += 2;
break;
}
}
console.log(
"part one:",
computer.Output.join(","),
printTime(now.instant().since(timer))
);
// timer = now.instant();
// console.log("part two:", computer, printTime(now.instant().since(timer)));