well part 1 was straightforward... is the solution for part 2 to run it in reverse?
This commit is contained in:
parent
be9e7619cd
commit
6a472c73e8
117
17/index.ts
Normal file
117
17/index.ts
Normal 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)));
|
Loading…
Reference in New Issue
Block a user