From b0dbc987667f1fee1a3d629584b850f23375d3a6 Mon Sep 17 00:00:00 2001 From: Andres Date: Wed, 11 Dec 2024 15:50:27 +0100 Subject: [PATCH] 2024 day 11 final --- 2024/day-11/blink-worker.ts | 40 -------------------- 2024/day-11/day11.test.ts | 17 +++------ 2024/day-11/day11.ts | 74 ++++++++++++++++++++++++------------- 2024/day-11/workers.ts | 30 --------------- 4 files changed, 54 insertions(+), 107 deletions(-) delete mode 100644 2024/day-11/blink-worker.ts delete mode 100644 2024/day-11/workers.ts diff --git a/2024/day-11/blink-worker.ts b/2024/day-11/blink-worker.ts deleted file mode 100644 index de69133..0000000 --- a/2024/day-11/blink-worker.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { parentPort, workerData } from "node:worker_threads"; - -const cache = new Map>(); - -function transformSingleStone(stone: number): number[] { - if (cache.has(stone)) { - // biome-ignore lint/style/noNonNullAssertion: it's there, I promise - return cache.get(stone)!; - } - if (stone === 0) { - cache.set(stone, [1]); - return [1]; - } - const numberAsString = stone.toString(); - const numberOfDigits = numberAsString.length; - if (numberOfDigits % 2 === 0) { - const middle = numberOfDigits / 2; - const left = numberAsString.slice(0, middle); - const right = numberAsString.slice(middle); - const res = [Number.parseInt(left, 10), Number.parseInt(right, 10)]; - cache.set(stone, res); - return res; - } - - const res = [stone * 2024]; - cache.set(stone, res); - return res; -} - -function blink(stones: Array) { - const newStones: number[] = []; - for (const stone of stones) { - newStones.push(...transformSingleStone(stone)); - } - return newStones; -} - -const result = blink(workerData); - -parentPort?.postMessage(result); diff --git a/2024/day-11/day11.test.ts b/2024/day-11/day11.test.ts index e809fcf..e6e666b 100644 --- a/2024/day-11/day11.test.ts +++ b/2024/day-11/day11.test.ts @@ -10,9 +10,9 @@ test("day 11, part 1", async () => { console.log("\n\n"); - // const testResult = part1(testInput); - // console.log("Test data:", testResult); - // expect(testResult).toEqual(55312); + const testResult = part1(testInput); + console.log("Test data:", testResult); + expect(testResult).toEqual(55312); const finalResult = await part1(input); console.log("Full data:", finalResult); @@ -27,14 +27,9 @@ test("day 11, part 2", async () => { ).text(); const input = await Bun.file(path.resolve(__dirname, "input.txt")).text(); - const testResult = part2(testInput); - console.log("\n\n"); - console.log("Test data:", testResult); - expect(testResult).toEqual(0); - - // const finalResult = part2(input); - // console.log("Full data:", finalResult); - // expect(finalResult).toEqual(0); + const finalResult = part2(input); + console.log("Full data:", finalResult); + expect(finalResult).toEqual(218279375708592); console.log("\n\n"); }); diff --git a/2024/day-11/day11.ts b/2024/day-11/day11.ts index bc32214..770ea97 100644 --- a/2024/day-11/day11.ts +++ b/2024/day-11/day11.ts @@ -1,35 +1,57 @@ -import { Worker } from "node:worker_threads"; +const cache = new Map(); -export async function part1(input: string) { +export function part1(input: string) { const lines = input.split("\n"); const line = lines[0]; const stones = line.split(" ").map(Number); - stones.length = 1; - // for (let i = 0; i < 75; i++) { - // console.log(i); - // stones = blink(stones); - // } - let final = 0; - await Promise.all( - stones.map(async (stone) => { - const sum = (await new Promise((res) => { - const worker = new Worker("./2024/day-11/workers.ts", { - workerData: stone, - }); - - worker.on("message", (result) => { - res(result); - }); - })) as number; - final += sum; - }), - ); - - return final; + let total = 0; + for (const stone of stones) { + total += count(stone, 25); + } + return total; } export function part2(input: string) { const lines = input.split("\n"); - const final = 0; - return final; + const line = lines[0]; + const stones = line.split(" ").map(Number); + let total = 0; + for (const stone of stones) { + total += count(stone, 75); + } + return total; +} + +function count(stone: number, steps: number): number { + const key = `${stone},${steps}`; + + if (cache.has(key)) { + return cache.get(key) as number; + } + + if (steps === 0) { + const res = 1; + cache.set(key, res); + return res; + } + if (stone === 0) { + const res = count(1, steps - 1); + cache.set(key, res); + return res; + } + const numberAsString = stone.toString(); + const numberOfDigits = numberAsString.length; + if (numberOfDigits % 2 === 0) { + const middle = numberOfDigits / 2; + const left = numberAsString.slice(0, middle); + const right = numberAsString.slice(middle); + const res = + count(Number.parseInt(left, 10), steps - 1) + + count(Number.parseInt(right, 10), steps - 1); + cache.set(key, res); + return res; + } + const res = count(stone * 2024, steps - 1); + cache.set(key, res); + return res; } diff --git a/2024/day-11/workers.ts b/2024/day-11/workers.ts deleted file mode 100644 index db7441f..0000000 --- a/2024/day-11/workers.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { Worker, parentPort, workerData } from "node:worker_threads"; -import { chunk } from "remeda"; -let stones = [workerData]; -for (let i = 0; i < 75; i++) { - console.log(i); - const chunks = chunk(stones, 5_000_000); - const newStones = await Promise.all( - chunks.map((chunk) => processChunk(chunk)), - ); - stones = newStones.flat(1); -} - -parentPort?.postMessage(stones.length); - -async function processChunk(chunk: number[]) { - console.log("processing chunk of length", chunk.length); - return await new Promise((res) => { - const worker = new Worker("./2024/day-11/blink-worker.ts", { - workerData: chunk, - }); - - worker.on("message", (result) => { - res(result); - }); - }); -} -// async function processChunk(chunk: number[]) { -// console.log("processing chunk of length", chunk.length); -// const result = await pool.exec("blink", [chunk]); -// }