From ba7d864c55526f42ec584cda4be0d5ff7c793dd0 Mon Sep 17 00:00:00 2001 From: TimHi Date: Thu, 21 Dec 2023 13:01:49 +0100 Subject: [PATCH] Day 21 Part 1 --- .../2023/src/days/__test__/day21.test.ts | 8 ++ Typescript/2023/src/days/day21/day21.ts | 92 +++++++++++++++++++ Typescript/2023/src/days/day21/sample.txt | 11 +++ Typescript/2023/src/main.ts | 7 +- 4 files changed, 116 insertions(+), 2 deletions(-) create mode 100644 Typescript/2023/src/days/__test__/day21.test.ts create mode 100644 Typescript/2023/src/days/day21/day21.ts create mode 100644 Typescript/2023/src/days/day21/sample.txt diff --git a/Typescript/2023/src/days/__test__/day21.test.ts b/Typescript/2023/src/days/__test__/day21.test.ts new file mode 100644 index 0000000..9871b9e --- /dev/null +++ b/Typescript/2023/src/days/__test__/day21.test.ts @@ -0,0 +1,8 @@ +import { SolvePartOne } from "../day21/day21"; +import { describe, expect, test } from "vitest"; + +describe("Day 21 Part 01", () => { + test("Expected result", () => { + expect(SolvePartOne()).toBe(16); + }); +}); diff --git a/Typescript/2023/src/days/day21/day21.ts b/Typescript/2023/src/days/day21/day21.ts new file mode 100644 index 0000000..3a2dc87 --- /dev/null +++ b/Typescript/2023/src/days/day21/day21.ts @@ -0,0 +1,92 @@ +import * as fs from "fs"; +import { GetPointKey, Point } from "../../util/coords"; + +import { Queue } from "data-structure-typed"; + +const isSample = true; + +interface GardenPosition extends Point { + symbol: string; +} + +function parseMap(input: string[][]): [Map, Point] { + const gardenMap = new Map(); + const startPos: Point = { X: 0, Y: 0 }; + for (let y = 0; y < input.length; y++) { + for (let x = 0; x < input[0].length; x++) { + const symbol = input[y][x]; + gardenMap.set(GetPointKey({ X: x, Y: y }), { symbol: symbol, X: x, Y: y }); + if (symbol === "S") { + startPos.X = x; + startPos.Y = y; + } + } + } + return [gardenMap, startPos]; +} + +export function SolvePartOne(): number { + const fileName = isSample ? "/src/days/day21/sample.txt" : "/src/days/day21/full.txt"; + const lines = fs + .readFileSync(process.cwd() + fileName, "utf8") + .split("\n") + .map((l) => l.split("")); + + const [map, start] = parseMap(lines); + const result = getPossibleEndpoints(map, start, lines[0].length, lines.length); + return result; +} + +function getPossibleEndpoints(map: Map, start: Point, xBound: number, yBound: number): number { + const deltas: Point[] = [ + { X: 1, Y: 0 }, + { X: -1, Y: 0 }, + { X: 0, Y: 1 }, + { X: 0, Y: -1 } + ]; + const maxSteps = isSample ? 6 : 64; + const reachedPositions = new Set(); + const Q = new Queue(); + const visited = new Set(); + Q.enqueue(makePointWithStepKey(start, 0)); + visited.add(makePointWithStepKey(start, 0)); + while (Q.size > 0) { + const v: string = Q.dequeue()!; + const [vPoint, stepsAtPoint] = getPointWithStepFromKey(v); + if (stepsAtPoint === maxSteps) { + reachedPositions.add(makePointWithStepKey(vPoint, stepsAtPoint)); + } + if (stepsAtPoint === maxSteps + 1) { + return reachedPositions.size; + } + deltas.forEach((delta) => { + const nextPoint: Point = { X: vPoint.X + delta.X, Y: vPoint.Y + delta.Y }; + + //Is Next Point in Map && not Wall + if (0 <= nextPoint.X && nextPoint.X < xBound && 0 <= nextPoint.Y && nextPoint.Y < yBound) { + if (map.get(GetPointKey(nextPoint))!.symbol !== "#") { + const key = makePointWithStepKey(nextPoint, stepsAtPoint + 1); + if (!visited.has(key)) { + Q.enqueue(key); + visited.add(key); + } + } + } + }); + } + return -1; +} + +export function SolvePartTwo(): number { + console.log("TBD"); + return 0; +} + +function getPointWithStepFromKey(key: string): [Point, number] { + const split = key.split(":"); + return [{ X: Number(split[0]), Y: Number(split[1]) }, Number(split[2])]; +} + +function makePointWithStepKey(p: Point, step: number): string { + return `${p.X}:${p.Y}:${step}`; +} diff --git a/Typescript/2023/src/days/day21/sample.txt b/Typescript/2023/src/days/day21/sample.txt new file mode 100644 index 0000000..c66328c --- /dev/null +++ b/Typescript/2023/src/days/day21/sample.txt @@ -0,0 +1,11 @@ +........... +.....###.#. +.###.##..#. +..#.#...#.. +....#.#.... +.##..S####. +.##..#...#. +.......##.. +.##.#.####. +.##..##.##. +........... \ No newline at end of file diff --git a/Typescript/2023/src/main.ts b/Typescript/2023/src/main.ts index 22c26af..c2a4f05 100644 --- a/Typescript/2023/src/main.ts +++ b/Typescript/2023/src/main.ts @@ -18,9 +18,9 @@ import { SolvePartOne as SolvePartOneD17, SolvePartTwo as SolvePartTwoD17 } from import { SolvePartOne as SolvePartOneD18, SolvePartTwo as SolvePartTwoD18 } from "./days/day18/day18"; import { SolvePartOne as SolvePartOneD19, SolvePartTwo as SolvePartTwoD19 } from "./days/day19/day19"; import { SolvePartOne as SolvePartOneD20, SolvePartTwo as SolvePartTwoD20 } from "./days/day20/day20"; - +import { SolvePartOne as SolvePartOneD21, SolvePartTwo as SolvePartTwoD21 } from "./days/day21/day21"; //Please don't look at this file I dont care its ugly -const day: number = 20; +const day: number = 21; if (day === 1) { console.log("Day 01 Part 01: " + SolvePartOne()); @@ -82,4 +82,7 @@ if (day === 1) { } else if (day === 20) { console.log("Day 20 Part 01: " + SolvePartOneD20()); console.log("Day 20 Part 02: " + SolvePartTwoD20()); +} else if (day === 21) { + console.log("Day 21 Part 01: " + SolvePartOneD21()); + console.log("Day 21 Part 02: " + SolvePartTwoD21()); }