From 3485e7ec80a54b8840bdd81f416af25f6637a744 Mon Sep 17 00:00:00 2001 From: Brad Adams Date: Thu, 19 Dec 2024 11:09:27 +0100 Subject: [PATCH] 19/2024 --- 2024/19/example.txt | 10 ++++++ 2024/19/index.test.ts | 25 ++++++++++++++ 2024/19/index.ts | 78 +++++++++++++++++++++++++++++++++++++++++++ README.md | 1 + 4 files changed, 114 insertions(+) create mode 100644 2024/19/example.txt create mode 100644 2024/19/index.test.ts create mode 100644 2024/19/index.ts diff --git a/2024/19/example.txt b/2024/19/example.txt new file mode 100644 index 0000000..ad43a74 --- /dev/null +++ b/2024/19/example.txt @@ -0,0 +1,10 @@ +r, wr, b, g, bwu, rb, gb, br + +brwrr +bggr +gbbr +rrbgbr +ubwu +bwurrg +brgr +bbrgwb \ No newline at end of file diff --git a/2024/19/index.test.ts b/2024/19/index.test.ts new file mode 100644 index 0000000..5074e26 --- /dev/null +++ b/2024/19/index.test.ts @@ -0,0 +1,25 @@ +import { expect, describe, test } from "bun:test"; +import { part1, part2 } from "."; +import { getInputs } from "../../utils/get-inputs"; + +const { exampleInput, puzzleInput } = await getInputs("2024/19"); + +describe("part 1", () => { + test("example", () => { + expect(part1(exampleInput)).toBe(6); + }); + + test("puzzle", () => { + expect(part1(puzzleInput)).toBe(358); + }); +}); + +describe("part 2", () => { + test("example", () => { + expect(part2(exampleInput)).toBe(16); + }); + + test("puzzle", () => { + expect(part2(puzzleInput)).toBe(600639829400603); + }); +}); diff --git a/2024/19/index.ts b/2024/19/index.ts new file mode 100644 index 0000000..c46037e --- /dev/null +++ b/2024/19/index.ts @@ -0,0 +1,78 @@ +import { timePart1, timePart2 } from "../../utils/time-part"; + +const parseInput = (input: string) => { + const [availableTowels, designs] = input.split("\n\n"); + + return { + availableTowels: availableTowels.split(", "), + designs: designs.split("\n"), + }; +}; + +export const part1 = timePart1((input: string) => { + const { availableTowels, designs } = parseInput(input); + let possibleDesigns = 0; + + for (const design of designs) { + let queue: Array<{ remaining: string }> = []; + + for (const towel of availableTowels) { + if (design.indexOf(towel) === 0) { + queue.push({ remaining: design.substring(towel.length) }); + } + } + + while (queue.length) { + queue.sort((a, b) => a.remaining.length - b.remaining.length); + const entry = queue.shift()!; + + for (const towel of availableTowels) { + if (entry.remaining.indexOf(towel) === 0) { + if (entry.remaining.length === towel.length) { + possibleDesigns++; + queue = []; + break; + } + + queue.push({ remaining: entry.remaining.substring(towel.length) }); + } + } + } + } + + return possibleDesigns; +}); + +export const part2 = timePart2((input: string) => { + const { availableTowels, designs } = parseInput(input); + let possibleDesigns = 0; + const canBeCompleted = new Map(); + + const countTowelVariants = (remaining: string) => { + if (canBeCompleted.has(remaining)) { + return canBeCompleted.get(remaining)!; + } + + let variants = 0; + + for (const towel of availableTowels) { + if (remaining.indexOf(towel) === 0) { + if (remaining.length === towel.length) { + variants++; + continue; + } + + variants += countTowelVariants(remaining.substring(towel.length)); + } + } + + canBeCompleted.set(remaining, variants); + return variants; + }; + + for (const design of designs) { + possibleDesigns += countTowelVariants(design); + } + + return possibleDesigns; +}); diff --git a/README.md b/README.md index d0e4de5..cbbc57c 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,7 @@ | Day | Part 1 | Part 2 | | :----------------------------------------: | :----: | :----: | +| [19](https://adventofcode.com/2024/day/19) | ✅ | ✅ | | [18](https://adventofcode.com/2024/day/18) | ✅ | ✅ | | [17](https://adventofcode.com/2024/day/17) | ✅ | ✅ | | [16](https://adventofcode.com/2024/day/16) | ✅ | ✅ |