Skip to content

Commit 5dea1fe

Browse files
committed
feat: 2024 Day 22
1 parent 85e06a5 commit 5dea1fe

File tree

6 files changed

+96
-0
lines changed

6 files changed

+96
-0
lines changed

2024/day/22/part/1/solve.test.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import solve from "./solve.ts";
2+
3+
import { assertEquals } from "@std/assert";
4+
5+
Deno.test("example", () => {
6+
const input = `\
7+
1
8+
10
9+
100
10+
2024`;
11+
12+
assertEquals(solve(input), 37327623);
13+
});

2024/day/22/part/1/solve.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import { generateSecrets } from "../../secrets.ts";
2+
3+
export default function solve(input: string) {
4+
const initialSecrets = input.split("\n").map(Number);
5+
let sum = 0;
6+
for (const initialSecret of initialSecrets) {
7+
sum += generateSecrets(initialSecret).at(-1)!;
8+
}
9+
return sum;
10+
}

2024/day/22/part/2/solve.test.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import solve from "./solve.ts";
2+
3+
import { assertEquals } from "@std/assert";
4+
5+
Deno.test("example", () => {
6+
const input = `\
7+
1
8+
2
9+
3
10+
2024`;
11+
12+
assertEquals(solve(input), 23);
13+
});

2024/day/22/part/2/solve.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import { generateSecrets } from "../../secrets.ts";
2+
3+
export default function solve(input: string) {
4+
const initialSecrets = input.split("\n").map(Number);
5+
const sequenceToTotalPrice = new Map<string, number>();
6+
for (const initialSecret of initialSecrets) {
7+
const sequenceToPrice = new Map<string, number>();
8+
const sequence: number[] = [];
9+
let prevPrice = Number(initialSecret % 10);
10+
for (const secret of generateSecrets(initialSecret)) {
11+
if (sequence.length === 4) sequence.shift();
12+
const price = secret % 10;
13+
sequence.push(price - prevPrice);
14+
prevPrice = price;
15+
if (sequence.length < 4) continue;
16+
const hash = sequence.join(",");
17+
if (sequenceToPrice.has(hash)) continue;
18+
sequenceToPrice.set(hash, price);
19+
const total = sequenceToTotalPrice.get(hash) ?? 0;
20+
sequenceToTotalPrice.set(hash, total + price);
21+
}
22+
}
23+
return Math.max(...sequenceToTotalPrice.values());
24+
}

2024/day/22/secrets.test.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import { assertEquals } from "@std/assert";
2+
import { generateSecrets } from "./secrets.ts";
3+
4+
Deno.test("example", () => {
5+
assertEquals(generateSecrets(123, { limit: 10 }), [
6+
15887950,
7+
16495136,
8+
527345,
9+
704524,
10+
1553684,
11+
12683156,
12+
11100544,
13+
12249484,
14+
7753432,
15+
5908254,
16+
]);
17+
});

2024/day/22/secrets.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
function mix(secret: bigint, value: bigint) {
2+
return value ^ secret;
3+
}
4+
5+
function prune(secret: bigint) {
6+
return secret % 16777216n;
7+
}
8+
9+
export function generateSecrets(initialSecret: number, { limit = 2000 } = {}) {
10+
const result: number[] = [];
11+
let secret = BigInt(initialSecret);
12+
for (let n = 1; n <= limit; n++) {
13+
secret = prune(mix(secret, secret * 64n));
14+
secret = prune(mix(secret, secret / 32n));
15+
secret = prune(mix(secret, secret * 2048n));
16+
result.push(Number(secret));
17+
}
18+
return result;
19+
}

0 commit comments

Comments
 (0)