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

Lines changed: 5 additions & 0 deletions
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

Lines changed: 33 additions & 0 deletions
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

Lines changed: 127 additions & 0 deletions
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

Lines changed: 1 addition & 0 deletions
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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy