diff --git a/2024/20/index.test.ts b/2024/20/index.test.ts
index feb69c4..afd96c8 100644
--- a/2024/20/index.test.ts
+++ b/2024/20/index.test.ts
@@ -21,8 +21,12 @@ describe('2024-20', () => {
expect(solveFirst(testInput, 1)).toBe(14 + 14 + 2 + 4 + 2 + 3 + 5);
});
it('second', () => {
- expect(solveSecond(testInput, 50)).toBe(
- 32 + 31 + 29 + 39 + 25 + 23 + 20 + 19 + 12 + 14 + 12 + 22 + 4 + 3
- );
+ // it takes too long
+ // so only run while `NODE_ENV=production bun test --coverage`
+ if (process.env.NODE_ENV === 'production') {
+ expect(solveSecond(testInput, 50)).toBe(
+ 32 + 31 + 29 + 39 + 25 + 23 + 20 + 19 + 12 + 14 + 12 + 22 + 4 + 3
+ );
+ }
});
});
diff --git a/2024/21/index.test.ts b/2024/21/index.test.ts
index 5086329..e808853 100644
--- a/2024/21/index.test.ts
+++ b/2024/21/index.test.ts
@@ -8,6 +8,10 @@ describe('2024-21', () => {
179A
456A
379A`;
- expect(solveFirst(testInput)).toBe(126384);
+ // it takes too long
+ // so only run while `NODE_ENV=production bun test --coverage`
+ if (process.env.NODE_ENV === 'production') {
+ expect(solveFirst(testInput)).toBe(126384);
+ }
});
});
diff --git a/2024/22/2024-22.run.xml b/2024/22/2024-22.run.xml
new file mode 100644
index 0000000..6e14570
--- /dev/null
+++ b/2024/22/2024-22.run.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/2024/22/index.test.ts b/2024/22/index.test.ts
new file mode 100644
index 0000000..b461cd9
--- /dev/null
+++ b/2024/22/index.test.ts
@@ -0,0 +1,23 @@
+import { describe, expect, it } from 'bun:test';
+import { solveFirst, solveSecond } from './index.ts';
+
+describe('2024-22', () => {
+ it('first', () => {
+ const testInput = `1
+10
+100
+2024`;
+ expect(solveFirst(testInput)).toBe(37327623);
+ });
+ it('second', () => {
+ // it takes too long
+ // so only run while `NODE_ENV=production bun test --coverage`
+ if (process.env.NODE_ENV === 'production') {
+ const testInput = `1
+2
+3
+2024`;
+ expect(solveSecond(testInput)).toBe(23);
+ }
+ });
+});
diff --git a/2024/22/index.ts b/2024/22/index.ts
new file mode 100644
index 0000000..d77e197
--- /dev/null
+++ b/2024/22/index.ts
@@ -0,0 +1,88 @@
+import { Presets, SingleBar } from 'cli-progress';
+import { sumArray } from '../../utils/array.ts';
+import { mod } from '../../utils/numbers.ts';
+
+export function solveFirst(input: string): number {
+ const start = input.split('\n').map(Number);
+
+ const end = start.map((v) => {
+ let value = v;
+ for (let i = 0; i < 2000; i++) {
+ value = mod((value * 64) ^ value, 16777216);
+ value = mod(Math.floor(value / 32) ^ value, 16777216);
+ value = mod((value * 2048) ^ value, 16777216);
+ }
+ return value;
+ });
+ return sumArray(end);
+}
+
+type Sequence = [number, number, number, number];
+
+function findPriceBySequence(
+ prices: [number, number][],
+ sequence: Sequence
+): number {
+ return (
+ prices.find(
+ (p, i, a) => i >= 4 && sequence.every((s, si) => s === a[i - (3 - si)][1])
+ )?.[0] || 0
+ );
+}
+
+function getSequences(prices: [number, number][]): string[] {
+ const sequences = new Array(prices.length - 4);
+ for (let i = 4; i < prices.length; i++) {
+ sequences[i - 4] = [
+ prices[i - 3][1],
+ prices[i - 2][1],
+ prices[i - 1][1],
+ prices[i][1]
+ ].join(',');
+ }
+ return sequences;
+}
+
+export function solveSecond(input: string): number {
+ const start = input.split('\n').map(Number);
+
+ const prices = start.map((v) => {
+ let value = v;
+ const sec = new Array<[number, number]>(2000);
+ sec[0] = [mod(value, 10), 0];
+ let lastPrice = sec[0][0];
+ for (let i = 0; i < 2000; i++) {
+ value = mod((value * 64) ^ value, 16777216);
+ value = mod(Math.floor(value / 32) ^ value, 16777216);
+ value = mod((value * 2048) ^ value, 16777216);
+ const price = mod(value, 10);
+ sec[i + 1] = [price, price - lastPrice];
+ lastPrice = price;
+ }
+ return sec;
+ });
+
+ const sequences = prices.flatMap((p) => getSequences(p));
+ const uniqueSequences = new Set(sequences);
+ const bar =
+ process.env.NODE_ENV === 'test'
+ ? null
+ : new SingleBar({}, Presets.shades_classic);
+ bar?.start(uniqueSequences.size, 0);
+ let highestPrice = 0;
+
+ for (let sequence of uniqueSequences) {
+ const numSequence = sequence.split(',').map(Number) as Sequence;
+ const finalPrices = sumArray(
+ prices.map((p) => findPriceBySequence(p, numSequence))
+ );
+
+ if (finalPrices > highestPrice) {
+ highestPrice = finalPrices;
+ }
+ bar?.increment();
+ }
+ bar?.stop();
+
+ return highestPrice;
+}
diff --git a/2024/22/run.ts b/2024/22/run.ts
new file mode 100644
index 0000000..88783cd
--- /dev/null
+++ b/2024/22/run.ts
@@ -0,0 +1,12 @@
+import { join } from 'path';
+import { solveFirst, solveSecond } from './index.ts';
+
+const input = await Bun.file(join(__dirname, 'input.txt')).text();
+
+const firstAnswer = solveFirst(input);
+
+console.log(firstAnswer);
+
+const secondAnswer = solveSecond(input);
+
+console.log(secondAnswer);