From fd01ee545ef4c2718ab8da4a76ae548195677774 Mon Sep 17 00:00:00 2001 From: Pascal Syma Date: Sun, 22 Dec 2024 14:54:10 +0100 Subject: [PATCH] Solve 2024-22 --- 2024/20/index.test.ts | 10 +++-- 2024/21/index.test.ts | 6 ++- 2024/22/2024-22.run.xml | 7 ++++ 2024/22/index.test.ts | 23 +++++++++++ 2024/22/index.ts | 88 +++++++++++++++++++++++++++++++++++++++++ 2024/22/run.ts | 12 ++++++ 6 files changed, 142 insertions(+), 4 deletions(-) create mode 100644 2024/22/2024-22.run.xml create mode 100644 2024/22/index.test.ts create mode 100644 2024/22/index.ts create mode 100644 2024/22/run.ts 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);