Skip to content

Commit 127eee9

Browse files
committed
17/2024
1 parent d03d5c2 commit 127eee9

File tree

4 files changed

+166
-0
lines changed

4 files changed

+166
-0
lines changed

2024/17/example.txt

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
Register A: 729
2+
Register B: 0
3+
Register C: 0
4+
5+
Program: 0,1,5,4,3,0

2024/17/index.test.ts

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import { expect, describe, test } from "bun:test";
2+
import { part1, part2 } from ".";
3+
import { getInputs } from "../../utils/get-inputs";
4+
5+
const { exampleInput, puzzleInput } = await getInputs("2024/17");
6+
7+
describe("part 1", () => {
8+
test("example", () => {
9+
expect(part1(exampleInput)).toBe("4,6,3,5,6,3,5,2,1,0");
10+
});
11+
12+
test("puzzle", () => {
13+
expect(part1(puzzleInput)).toBe("7,1,3,4,1,2,6,7,1");
14+
});
15+
});
16+
17+
const exampleInputForPart2 = `
18+
Register A: 2024
19+
Register B: 0
20+
Register C: 0
21+
22+
Program: 0,3,5,4,3,0
23+
`.trim();
24+
25+
describe("part 2", () => {
26+
test("example", () => {
27+
expect(part2(exampleInputForPart2)).toBe("117440");
28+
});
29+
30+
test("puzzle", () => {
31+
expect(part2(puzzleInput)).toBe("109019476330651");
32+
});
33+
});

2024/17/index.ts

+127
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
import { timePart1, timePart2 } from "../../utils/time-part";
2+
3+
const parseInput = (input: string) => {
4+
const [registers, program] = input.split("\n\n");
5+
6+
const [a, b, c] = registers
7+
.split("\n")
8+
.map((register) => BigInt(register.split(": ")[1]));
9+
10+
return {
11+
registers: { a, b, c },
12+
program: program.split(": ")[1].split(",").map(BigInt),
13+
};
14+
};
15+
16+
const modulo = (a: bigint, b: bigint) => ((a % b) + b) % b;
17+
18+
const getComboOperand = (
19+
literalOperand: bigint,
20+
registers: ReturnType<typeof parseInput>["registers"]
21+
) => {
22+
if (literalOperand === 4n) return registers.a;
23+
if (literalOperand === 5n) return registers.b;
24+
if (literalOperand === 6n) return registers.c;
25+
26+
return literalOperand;
27+
};
28+
29+
const runProgram = ({ program, registers }: ReturnType<typeof parseInput>) => {
30+
let output: bigint[] = [];
31+
32+
let i = 0;
33+
while (true) {
34+
if (i >= program.length) {
35+
break;
36+
}
37+
38+
const opcode = program[i];
39+
const operandIndex = i + 1;
40+
41+
if (operandIndex >= program.length) {
42+
break;
43+
}
44+
45+
const literalOperand = program[operandIndex];
46+
const comboOperand = getComboOperand(literalOperand, registers);
47+
48+
// adv
49+
if (opcode === 0n) {
50+
registers.a = registers.a / 2n ** comboOperand;
51+
}
52+
53+
// bxl
54+
if (opcode === 1n) {
55+
registers.b = registers.b ^ literalOperand;
56+
}
57+
58+
// bst
59+
if (opcode === 2n) {
60+
registers.b = modulo(comboOperand, 8n);
61+
}
62+
63+
// jnz
64+
if (opcode === 3n && registers.a !== 0n) {
65+
i = Number(literalOperand);
66+
continue;
67+
}
68+
69+
// bxc
70+
if (opcode === 4n) {
71+
registers.b = registers.b ^ registers.c;
72+
}
73+
74+
// out
75+
if (opcode === 5n) {
76+
output.push(modulo(comboOperand, 8n));
77+
}
78+
79+
// bdv
80+
if (opcode === 6n) {
81+
registers.b = registers.a / 2n ** comboOperand;
82+
}
83+
84+
// cdv
85+
if (opcode === 7n) {
86+
registers.c = registers.a / 2n ** comboOperand;
87+
}
88+
89+
// Skip operand
90+
i += 2;
91+
}
92+
93+
return output.join(",");
94+
};
95+
96+
export const part1 = timePart1((input: string) => {
97+
const { program, registers } = parseInput(input);
98+
99+
return runProgram({ program, registers });
100+
});
101+
102+
export const part2 = timePart2((input: string) => {
103+
const { program, registers } = parseInput(input);
104+
105+
const programStr = program.join(",");
106+
let a = 0n;
107+
108+
while (true) {
109+
const output = runProgram({ program, registers: { ...registers, a } });
110+
111+
if (output === programStr) {
112+
break;
113+
}
114+
115+
// Once we _start_ to find a match
116+
if (programStr.indexOf(output) + output.length === programStr.length) {
117+
// Just increment in instances of 8 times the value of the `A` register
118+
a = a * 8n;
119+
120+
continue;
121+
}
122+
123+
a++;
124+
}
125+
126+
return a.toString();
127+
});

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
| Day | Part 1 | Part 2 |
88
| :----------------------------------------: | :----: | :----: |
9+
| [17](https://adventofcode.com/2024/day/17) |||
910
| [16](https://adventofcode.com/2024/day/16) |||
1011
| [15](https://adventofcode.com/2024/day/15) |||
1112
| [14](https://adventofcode.com/2024/day/14) |||

0 commit comments

Comments
 (0)