From 30a29c2bf610cdc89c10310129f8225eeebc2069 Mon Sep 17 00:00:00 2001 From: martapanc Date: Wed, 11 Dec 2024 20:21:32 +0100 Subject: [PATCH] 2024D11: Part 2 --- 2024/src/2024/day11/day11.test.ts | 12 ++++----- 2024/src/2024/day11/day11.ts | 45 +++++++++++++++++++++---------- 2 files changed, 37 insertions(+), 20 deletions(-) diff --git a/2024/src/2024/day11/day11.test.ts b/2024/src/2024/day11/day11.test.ts index 9767811..93f68aa 100644 --- a/2024/src/2024/day11/day11.test.ts +++ b/2024/src/2024/day11/day11.test.ts @@ -1,4 +1,4 @@ -import {blink, part1, part2} from "./day11"; +import {blinkV1, part1, part2} from "./day11"; const input = "41078 18 7 0 4785508 535256 8154 447"; const testInput1 = "0 1 10 99 999"; @@ -11,13 +11,13 @@ describe('2024 Day 11', () => { }); test('Part 2', async () => { - expect(await part2(input)).toEqual(217443); + expect(await part2(input)).toEqual(257246536026785); }); }); test('blink', () => { - expect(blink(testInput1).join(" ")).toEqual("1 2024 1 0 9 9 2021976") - expect(blink(testInput2).join(" ")).toEqual("253000 1 7") - expect(blink(blink(testInput2)).join(" ")).toEqual("253 0 2024 14168") - expect(blink(blink(blink(testInput2))).join(" ")).toEqual("512072 1 20 24 28676032") + expect(blinkV1(testInput1).join(" ")).toEqual("1 2024 1 0 9 9 2021976") + expect(blinkV1(testInput2).join(" ")).toEqual("253000 1 7") + expect(blinkV1(blinkV1(testInput2)).join(" ")).toEqual("253 0 2024 14168") + expect(blinkV1(blinkV1(blinkV1(testInput2))).join(" ")).toEqual("512072 1 20 24 28676032") }); \ No newline at end of file diff --git a/2024/src/2024/day11/day11.ts b/2024/src/2024/day11/day11.ts index 9bfb47a..6eaa7e1 100644 --- a/2024/src/2024/day11/day11.ts +++ b/2024/src/2024/day11/day11.ts @@ -1,10 +1,9 @@ - export async function part1(inputString: string) { - return await day11(inputString, 25); + return day11(inputString, 25); } export async function part2(inputString: string) { - return await day11(inputString, 75); + return day11(inputString, 75); } async function day11(inputString: string, times: number) { @@ -12,21 +11,39 @@ async function day11(inputString: string, times: number) { } function calcBlinkOutput(stones: string[], times: number) { - let expandedStonesCount= 0; + let stoneCounts: Map = new Map(); stones.forEach(stone => { - expandedStonesCount += blinkNtimes([stone], times); - }) - - return expandedStonesCount; -} + stoneCounts.set(stone, (stoneCounts.get(stone) || 0) + 1); + }); -function blinkNtimes(stones: string[], times: number) { - let expandedStones = [...stones]; for (let i = 0; i < times; i++) { - expandedStones = blink(expandedStones); + stoneCounts = blink(stoneCounts); } - return expandedStones.length; + + return Array.from(stoneCounts.values()) + .reduce((sum, count) => sum + count, 0); +} + +function blink(stoneCounts: Map): Map { + const newStoneCounts: Map = new Map(); + + stoneCounts.forEach((count, stone) => { + if (stone === '0') { + newStoneCounts.set('1', (newStoneCounts.get('1') || 0) + count); + } else if (stone.length % 2 === 0) { + const half = stone.length / 2; + const first = Number.parseInt(stone.slice(0, half)) + ''; + const second = Number.parseInt(stone.slice(half)) + ''; + newStoneCounts.set(first, (newStoneCounts.get(first) || 0) + count); + newStoneCounts.set(second, (newStoneCounts.get(second) || 0) + count); + } else { + const multiplied = (Number.parseInt(stone) * 2024) + ''; + newStoneCounts.set(multiplied, (newStoneCounts.get(multiplied) || 0) + count); + } + }); + + return newStoneCounts; } // Every time you blink, the stones each simultaneously change according to the _first applicable_ rule in this list: @@ -36,7 +53,7 @@ function blinkNtimes(stones: string[], times: number) { // The left half of the digits are engraved on the new left stone, and the right half of the digits are engraved on the new right stone. // 3. If none of the other rules apply, the stone is replaced by a new stone; // the old stone's number multiplied by 2024 is engraved on the new stone. -export function blink(stones: string[] | string): string[] { +export function blinkV1(stones: string[] | string): string[] { const inputStones = typeof stones === 'string' ? stones.split(" ") : stones; const updatedStones: string[] = [];