From f30c5ad87496d9a1f7e004ff1a6ce1ce202fd8aa Mon Sep 17 00:00:00 2001 From: AlexAegis Date: Mon, 11 Dec 2023 07:00:56 +0100 Subject: [PATCH] feat: solved 2023 day 11 --- .github/badges/typescript/2023.json | 2 +- resources/2023/11/example.1.txt | 10 ++ resources/2023/11/input.txt | 140 ++++++++++++++++++ solutions/typescript/2021/15/src/p1.ts | 2 +- solutions/typescript/2021/15/src/p2.ts | 2 +- solutions/typescript/2022/12/src/p1.ts | 2 +- solutions/typescript/2022/12/src/p2.ts | 2 +- solutions/typescript/2022/16/src/p1.ts | 2 +- solutions/typescript/2022/16/src/p2.ts | 2 +- solutions/typescript/2023/11/package.json | 5 - solutions/typescript/2023/11/src/p1.spec.ts | 4 +- solutions/typescript/2023/11/src/p1.ts | 23 ++- solutions/typescript/2023/11/src/p2.spec.ts | 4 +- solutions/typescript/2023/11/src/p2.ts | 23 ++- solutions/typescript/2023/11/src/parse.ts | 37 +++++ .../libs/lib/src/array/array.polyfill.ts | 4 +- .../libs/lib/src/array/filter-map.function.ts | 9 +- .../libs/lib/src/model/graph/graph.class.ts | 6 +- .../src/model/graph/grid-graph.class.bench.ts | 4 +- .../src/model/graph/grid-graph.class.spec.ts | 4 +- solutions/typescript/readme.md | 2 +- 21 files changed, 253 insertions(+), 36 deletions(-) create mode 100644 solutions/typescript/2023/11/src/parse.ts diff --git a/.github/badges/typescript/2023.json b/.github/badges/typescript/2023.json index ff50b1b70..0c72321dc 100644 --- a/.github/badges/typescript/2023.json +++ b/.github/badges/typescript/2023.json @@ -1,6 +1,6 @@ { "schemaVersion": 1, "label": "Advent of TypeScript 2023", - "message": "10/25", + "message": "11/25", "color": "orange" } diff --git a/resources/2023/11/example.1.txt b/resources/2023/11/example.1.txt index e69de29bb..986aad4a1 100644 --- a/resources/2023/11/example.1.txt +++ b/resources/2023/11/example.1.txt @@ -0,0 +1,10 @@ +...#...... +.......#.. +#......... +.......... +......#... +.#........ +.........# +.......... +.......#.. +#...#..... diff --git a/resources/2023/11/input.txt b/resources/2023/11/input.txt index e69de29bb..8b0a49522 100644 --- a/resources/2023/11/input.txt +++ b/resources/2023/11/input.txt @@ -0,0 +1,140 @@ +.....................................................................................#......#............................................... +..#.....#.................................................................#........................#........................................ +...............................#...............................................................................#.....#...................... +.................................................#.............#...............................#...................................#........ +..............#......#.................#...............#............#.............#..........................................#.............. +.........................................................................................#.................#...............................# +.#.......................................................................................................................................... +..........................#......#............................................#......#.................................#.................... +.................................................................................................#.......................................... +.........................................#..........#..........#............................................................#............... +......#.....#......#..........................#........................#.................................................................... +....................................#.........................................................................#..........................#.. +..................................................................................#......................................................... +...................................................................................................................#........................ +.................................................................#........................................#................................. +.............................#..............................#..........................#.......#............................................ +..........................................#.....#.............................#............................................................. +#..................#..................................................................................................................#..... +....................................#...................#..........................#...........................#..............#............. +........#................#...................#.............................................................................................# +...............................#....................#...........................................#........................................... +.......................................#..............................................#..................................................... +........................................................................#........#...........................#.............................. +..................................#........#...................#........................................#.........#.................#....... +#................#........................................................................................................#................. +.........#.......................................#...............................................#.............................#........#... +...............................................................................................................#............................ +.........................................................................................#.................................................. +...........................................................#..................................#..........#...........................#...... +......#.........................#..........................................................................................#................ +....................#.....................#.......#...............................#.................................#....................... +..........................#..............................................#.................................................................. +..........#..........................#.......................#...................................#..............#..............#...........# +......................................................#..................................................................................... +............................................................................................................................................ +#...............................................#................#............................#............................................. +..................#......................#............................#................................#................................#... +............................................................................................................................................ +....................................................#....................................#.............................#.................... +..............#...................#................................#..........#..............................#.............................# +............................#...............................................................................................#............... +....#.................#.....................................#..........#............................................................#....... +......................................................#..................................................................................... +...........#..............................#.................................................#..........#.................#.................. +.................................#..............#................#..........#.......#....................................................... +...................................................................................................................#..............#......... +#...........................................................................................................#............................... +........#.......#............................................................................................................#.............. +............................#.....................#..........#......................................#.....................................#. +.....................................#.................................................#........................#........................... +.........................................................................................................................#...........#...... +.......................#.............................#........................#............................................................. +..............#...............................#.................#..................#........#............................................... +...#......................................................................#.................................#..............................# +...................#..................#.............................................................................#........#.............. +............................................................................................................................................ +.........................#.........................#........................................................................................ +......#......#.............................................#.............................#............#..................................... +.................................#......................................#................................................................... +.........................................#........................#..............................#.................#..............#......... +............................................................................................................................................ +......................................................#.................................................#..............#..................#. +......................#......#...............#...................................#............................#............................. +....#...........#.................#............................................................#...............................#............ +..........................................................................#..........................#...................................... +..........................................#................................................#...............................#............#... +................................................................................................................#........................... +..........#....................................#...................................................................................#........ +................................#....................#..............................................................#....................... +......#.......................................................#...............................#............................................. +#.......................#.....................................................................................................#............. +.................#...................#...........................................#..........................#............................... +.....................................................................#....................#................................................. +..............................#.................#.......#.........................................#......................................... +..#........................................................................#....................................#.........#................. +...........#............................#..........................................#.............................................#.......... +......#.............................................................................................................#.....................#. +........................................................................................................#................................... +..............#...................#.........#............................................................................................... +........................................................#.............#..........#.....#..........#............................#............ +.........#......................................................#...........................#............................................... +.........................................#...................................#.................................#............................ +............................................................................................................................................ +................#...................................................................#.................#..................#.................. +.................................#..........................#.............#....................#................................#..........# +...#........................#.........................................................................................................#..... +.................................................#......................................#.....................#......#...................... +...........................................#.........................#........#............................................................. +........#......#...................................................................................................................#.....#.. +.#..................#..................................#.........#.......................................................................... +..................................#.....#.................................#................................................................. +...................................................#.................................#...................................................... +............................................................#............................................................................... +.............................................#......................#..........#............#.........................#......#.............. +................................#...................................................................#....................................... +.....................................................#..................#......................................#............................ +...#......................#.....................................................................................................#........... +...........#...........................................................................#..............................................#..... +................#..................................................#..............................................#......................... +.......................#......................................................................#............................................. +................................#........#.........#.....................#.....#......................#..................................... +.#.......................................................................................................................................... +........................................................#................................#...................#..................#........... +.....................................#........#.................................................#.......................................#... +.........#...........#...................................................................................................................... +....................................................#.............................................................#.................#....... +.............#............#........................................#.............#.....................#...................#...............# +..................#....................#.................................#.............#.................................................... +................................................#........................................................................................... +.......................#...............................................................................................#.................... +....#..........................................................#.....#..............#...........................................#........... +...............................................................................................#..................#.......................#. +.........#...................#............................................#................................................................. +.............................................................................................................#..............#......#........ +...........................................................................................#................................................ +.#...........................................................#.............................................................................. +..............#..............................#........................................#.............#....................................... +....................................#..............#..............#.........#.............................#.............#.............#..... +....................#............................................................................................#.......................... +.........................................................................................#.................................................. +...........#............................#................#....................................................................#............. +.....#......................................................................................................#............................... +..................................#................................................#........#.............................................#. +.#................#......#...........................................................................#...................................... +..............................................#.......................#................#............................................#....... +.........#............................#........................#..........................................#.....#......#.................... +..............................................................................................#............................................. +........................................................................................................................................#... +..........................#........................#...............#................................#............................#.......... +..#........................................#............#............................................................#...................... +...............................#.....#........................................#.......#......................................#.............. +.......................................................................................................#.................................... +.....................................................#..............................................................................#....... +........#......................................#...........................#.............................................#.................# +...................#.....#......................................#.............................#............................................. +............#.........................#......................................................................#.......#.................#.... +..............................#...................................................#......................................................... +............................................#.........................................................#..................................... +.......#..........................#................#.....#.............#.................................................................... +..................#.........................................................#.............#.......................................#......... diff --git a/solutions/typescript/2021/15/src/p1.ts b/solutions/typescript/2021/15/src/p1.ts index c3ca79d6e..da062e8bd 100644 --- a/solutions/typescript/2021/15/src/p1.ts +++ b/solutions/typescript/2021/15/src/p1.ts @@ -13,7 +13,7 @@ export const p1 = (input: string): number => { const start = graph.getNode(boundingBox.topLeft); const end = graph.getNode(boundingBox.bottomRight); - const path = graph.aStar(start, end, { + const { path } = graph.aStar(start, end, { heuristic: (_currentNode, tentativePath) => tentativePath.map((n) => n.value).sum(), }); diff --git a/solutions/typescript/2021/15/src/p2.ts b/solutions/typescript/2021/15/src/p2.ts index fdfd48425..1676765fb 100644 --- a/solutions/typescript/2021/15/src/p2.ts +++ b/solutions/typescript/2021/15/src/p2.ts @@ -52,7 +52,7 @@ export const p2 = (input: string): number => { const start = graph.getNode(boundingBox.topLeft); const end = graph.getNode(boundingBox.bottomRight); - const path = graph.aStar(start, end, { + const { path } = graph.aStar(start, end, { heuristic: (_a, p) => p.map((n) => n.value).sum(), }); diff --git a/solutions/typescript/2022/12/src/p1.ts b/solutions/typescript/2022/12/src/p1.ts index 211b67ff4..266403b5a 100644 --- a/solutions/typescript/2022/12/src/p1.ts +++ b/solutions/typescript/2022/12/src/p1.ts @@ -19,7 +19,7 @@ export const p1 = (input: string): number => { throw new Error('No path found'); } - return graph.aStar(start, end).length - 1; + return graph.aStar(start, end).path.length - 1; }; await task(p1, packageJson.aoc); // 534 ~83.84ms diff --git a/solutions/typescript/2022/12/src/p2.ts b/solutions/typescript/2022/12/src/p2.ts index 6a12f4c73..79dd81f8a 100644 --- a/solutions/typescript/2022/12/src/p2.ts +++ b/solutions/typescript/2022/12/src/p2.ts @@ -14,7 +14,7 @@ export const p2 = (input: string): number => { const start = graph.findNode((n) => n.value === 'E'); - return graph.aStar(start, (n) => n.value === 'a').length - 1; + return graph.aStar(start, (n) => n.value === 'a').path.length - 1; }; await task(p2, packageJson.aoc); // 525 ~140.04ms diff --git a/solutions/typescript/2022/16/src/p1.ts b/solutions/typescript/2022/16/src/p1.ts index 5b6d678a7..02ac9dd6d 100644 --- a/solutions/typescript/2022/16/src/p1.ts +++ b/solutions/typescript/2022/16/src/p1.ts @@ -13,7 +13,7 @@ const pathBetweenValves = memoize( ): GraphNode[] => { const from = graph.getNode(fromValve); const to = graph.getNode(toValve); - return graph.aStar(from, to); + return graph.aStar(from, to).path; }, ); diff --git a/solutions/typescript/2022/16/src/p2.ts b/solutions/typescript/2022/16/src/p2.ts index b907664e8..2c17d2eb2 100644 --- a/solutions/typescript/2022/16/src/p2.ts +++ b/solutions/typescript/2022/16/src/p2.ts @@ -13,7 +13,7 @@ const pathBetweenValves = memoize( ): GraphNode[] => { const from = graph.getNode(fromValve); const to = graph.getNode(toValve); - return graph.aStar(from, to); + return graph.aStar(from, to).path; }, ); diff --git a/solutions/typescript/2023/11/package.json b/solutions/typescript/2023/11/package.json index 7e4acc589..537e64089 100644 --- a/solutions/typescript/2023/11/package.json +++ b/solutions/typescript/2023/11/package.json @@ -61,11 +61,6 @@ "import": "./dist/p2.js", "default": "./dist/p2.js" }, - "./parse": { - "types": "./src/parse.ts", - "import": "./dist/parse.js", - "default": "./dist/parse.js" - }, "./readme": "./readme.md" }, "dependencies": { diff --git a/solutions/typescript/2023/11/src/p1.spec.ts b/solutions/typescript/2023/11/src/p1.spec.ts index 2a36112f3..7a22a0e3c 100644 --- a/solutions/typescript/2023/11/src/p1.spec.ts +++ b/solutions/typescript/2023/11/src/p1.spec.ts @@ -7,14 +7,14 @@ describe('2023 11 p1', () => { describe('the input', () => { it('should solve the input', async () => { const resources = await loadTaskResources(packageJson.aoc); - expect(p1(resources.input)).toEqual(0); + expect(p1(resources.input)).toEqual(10_228_230); }); }); describe('example 1', () => { it('should be solved', async () => { const resources = await loadTaskResources(packageJson.aoc, 'example.1.txt'); - expect(p1(resources.input)).toEqual(0); + expect(p1(resources.input)).toEqual(374); }); }); }); diff --git a/solutions/typescript/2023/11/src/p1.ts b/solutions/typescript/2023/11/src/p1.ts index d508a960e..510847195 100644 --- a/solutions/typescript/2023/11/src/p1.ts +++ b/solutions/typescript/2023/11/src/p1.ts @@ -1,8 +1,23 @@ -import { task } from '@alexaegis/advent-of-code-lib'; +import { BoundingBox, task } from '@alexaegis/advent-of-code-lib'; import packageJson from '../package.json'; +import { parse } from './parse.js'; -export const p1 = (_input: string): number => { - return 0; +export const p1 = (input: string): number => { + const { galaxies, emptyRows, emptyColumns } = parse(input); + + return galaxies + .pairs() + .map(([a, b]) => { + const nonExpandedDistance = a.manhattan(b); + const galaxyBox = BoundingBox.fromVectors([a, b]); + const emptyRowCount = emptyRows.filter((i) => galaxyBox.vertical.contains(i)).length; + const emptyColumnCount = emptyColumns.filter((i) => + galaxyBox.horizontal.contains(i), + ).length; + + return nonExpandedDistance + emptyRowCount + emptyColumnCount; + }) + .sum(); }; -await task(p1, packageJson.aoc); // 0 ~0ms +await task(p1, packageJson.aoc); // 10228230 ~0ms diff --git a/solutions/typescript/2023/11/src/p2.spec.ts b/solutions/typescript/2023/11/src/p2.spec.ts index 02455c5e4..a05d29a20 100644 --- a/solutions/typescript/2023/11/src/p2.spec.ts +++ b/solutions/typescript/2023/11/src/p2.spec.ts @@ -7,14 +7,14 @@ describe('2023 11 p2', () => { describe('the input', () => { it('should solve the input', async () => { const { input } = await loadTaskResources(packageJson.aoc); - expect(p2(input)).toEqual(0); + expect(p2(input)).toEqual(447_073_334_102); }); }); describe('example 1', () => { it('should be solved', async () => { const { input } = await loadTaskResources(packageJson.aoc, 'example.1.txt'); - expect(p2(input)).toEqual(0); + expect(p2(input)).toEqual(82_000_210); }); }); }); diff --git a/solutions/typescript/2023/11/src/p2.ts b/solutions/typescript/2023/11/src/p2.ts index 68c39bd1c..440d9048c 100644 --- a/solutions/typescript/2023/11/src/p2.ts +++ b/solutions/typescript/2023/11/src/p2.ts @@ -1,8 +1,23 @@ -import { task } from '@alexaegis/advent-of-code-lib'; +import { BoundingBox, task } from '@alexaegis/advent-of-code-lib'; import packageJson from '../package.json'; +import { parse } from './parse.js'; -export const p2 = (_input: string): number => { - return 0; +export const p2 = (input: string): number => { + const { galaxies, emptyRows, emptyColumns } = parse(input); + + return galaxies + .pairs() + .map(([a, b]) => { + const nonExpandedDistance = a.manhattan(b); + const galaxyBox = BoundingBox.fromVectors([a, b]); + const emptyRowCount = emptyRows.filter((i) => galaxyBox.vertical.contains(i)).length; + const emptyColumnCount = emptyColumns.filter((i) => + galaxyBox.horizontal.contains(i), + ).length; + + return nonExpandedDistance + emptyRowCount * 999_999 + emptyColumnCount * 999_999; + }) + .sum(); }; -await task(p2, packageJson.aoc); // 0 ~0ms +await task(p2, packageJson.aoc); // 10228230 ~0ms diff --git a/solutions/typescript/2023/11/src/parse.ts b/solutions/typescript/2023/11/src/parse.ts new file mode 100644 index 000000000..9970dcb87 --- /dev/null +++ b/solutions/typescript/2023/11/src/parse.ts @@ -0,0 +1,37 @@ +import { Vec2 } from '@alexaegis/advent-of-code-lib'; + +export interface GalaxyMap { + galaxies: Vec2[]; + emptyRows: number[]; + emptyColumns: number[]; +} + +export const parse = (input: string): GalaxyMap => { + const gg = input.toGridGraph({ + weighter: (_a, _b) => 1, + }); + + const verticalIndices = gg.boundingBox().vertical.collectValues(); + const horizontalIndices = gg.boundingBox().horizontal.collectValues(); + + const emptyRows = verticalIndices + .map((y) => horizontalIndices.map((x) => new Vec2(x, y))) + .filterMap((column, i) => { + const colNodes = column.map((c) => gg.getNode(c)); + return colNodes.every((node) => node?.value === '.') ? i : undefined; + }); + + const emptyColumns = horizontalIndices + .map((x) => verticalIndices.map((y) => new Vec2(x, y))) + .filterMap((row, i) => { + const rowNodes = row.map((r) => gg.getNode(r)); + return rowNodes.every((node) => node?.value === '.') ? i : undefined; + }); + + const galaxies = gg.nodes + .valueArray() + .filter((node) => node.value !== '.') + .map((node) => node.coordinate); + + return { galaxies, emptyRows, emptyColumns }; +}; diff --git a/solutions/typescript/libs/lib/src/array/array.polyfill.ts b/solutions/typescript/libs/lib/src/array/array.polyfill.ts index 2651f82dd..4e1b34501 100644 --- a/solutions/typescript/libs/lib/src/array/array.polyfill.ts +++ b/solutions/typescript/libs/lib/src/array/array.polyfill.ts @@ -74,7 +74,7 @@ declare global { * Return the average value of the array */ mean(): number; - filterMap(mapFn: (t: T) => V | undefined): V[]; + filterMap(mapFn: (t: T, i: number) => V | undefined): V[]; partition(partitioner: (a: T) => boolean): [T[], T[]]; pairwise(callback: (a: T, b: T) => void): void; slideWindow(windowSize?: N, stepSize?: number): SizedTuple[]; @@ -187,7 +187,7 @@ Array.prototype.unique = function (this: T[], comparator?: (a: T, b: T) => bo return result; }; -Array.prototype.filterMap = function (mapFn: (t: T) => V | undefined): V[] { +Array.prototype.filterMap = function (mapFn: (t: T, i: number) => V | undefined): V[] { return filterMap(this, mapFn); }; diff --git a/solutions/typescript/libs/lib/src/array/filter-map.function.ts b/solutions/typescript/libs/lib/src/array/filter-map.function.ts index 5162b0ae9..af58d9231 100644 --- a/solutions/typescript/libs/lib/src/array/filter-map.function.ts +++ b/solutions/typescript/libs/lib/src/array/filter-map.function.ts @@ -1,12 +1,17 @@ import { nonNullish } from '../functions/non-nullish.function.js'; -export const filterMap = (array: Iterable, mapFn: (t: T) => V | undefined): V[] => { +export const filterMap = ( + array: Iterable, + mapFn: (t: T, i: number) => V | undefined, +): V[] => { const result: V[] = []; + let i = 0; for (const item of array) { - const value = mapFn(item); + const value = mapFn(item, i); if (nonNullish(value)) { result.push(value); } + i++; } return result; }; diff --git a/solutions/typescript/libs/lib/src/model/graph/graph.class.ts b/solutions/typescript/libs/lib/src/model/graph/graph.class.ts index 1e106474c..3e1ee6181 100644 --- a/solutions/typescript/libs/lib/src/model/graph/graph.class.ts +++ b/solutions/typescript/libs/lib/src/model/graph/graph.class.ts @@ -290,9 +290,9 @@ export class Graph< start: N | undefined, end: N | ((n: N, path: N[]) => boolean) | undefined, options?: GraphTraversalOptions, - ): N[] { + ): { path: N[]; gScore: Map } { if (!start || !end) { - return []; + return { path: [], gScore: new Map() }; } const openSet = new Set([start]); // q? @@ -351,6 +351,6 @@ export class Graph< } } - return Graph.generatePath(cameFrom, start, goal); + return { path: Graph.generatePath(cameFrom, start, goal), gScore }; } } diff --git a/solutions/typescript/libs/lib/src/model/graph/grid-graph.class.bench.ts b/solutions/typescript/libs/lib/src/model/graph/grid-graph.class.bench.ts index 42845aee3..05569c871 100644 --- a/solutions/typescript/libs/lib/src/model/graph/grid-graph.class.bench.ts +++ b/solutions/typescript/libs/lib/src/model/graph/grid-graph.class.bench.ts @@ -27,12 +27,12 @@ const graph = GridGraph.fromString(mazeStr, { graph.print(); const start = graph.getNode(new Vec2(1, 1))!; const goal = graph.getNode(new Vec2(11, 12))!; -const p = graph.aStar(start, goal, { +const { path } = graph.aStar(start, goal, { weighter: (a, b) => a.coordinate.dist(b.coordinate), }); console.log( graph.toString((node) => - p.some((pc) => node.coordinate.equals(pc.coordinate)) ? '#' : undefined, + path.some((pc) => node.coordinate.equals(pc.coordinate)) ? '#' : undefined, ), ); diff --git a/solutions/typescript/libs/lib/src/model/graph/grid-graph.class.spec.ts b/solutions/typescript/libs/lib/src/model/graph/grid-graph.class.spec.ts index 7dc986636..38bac0d67 100644 --- a/solutions/typescript/libs/lib/src/model/graph/grid-graph.class.spec.ts +++ b/solutions/typescript/libs/lib/src/model/graph/grid-graph.class.spec.ts @@ -40,7 +40,7 @@ describe('Grid Graph', () => { it('should find the shortest path', () => { const g = GridGraph.fromMatrix(matrix); const goal = g.getNode(finish)!; - const path = g.aStar(g.getNode(start), goal, { + const { path } = g.aStar(g.getNode(start), goal, { heuristic: (a) => a.coordinate.manhattan(goal.coordinate), }); expect(path.length).toEqual(10); @@ -51,7 +51,7 @@ describe('Grid Graph', () => { connectionDirections: Direction.allDirections, }); const goal = g.getNode(finish)!; - const path = g.aStar(g.getNode(start), goal, { + const { path } = g.aStar(g.getNode(start), goal, { heuristic: (a) => a.coordinate.manhattan(goal.coordinate), }); expect(path.length).toEqual(6); diff --git a/solutions/typescript/readme.md b/solutions/typescript/readme.md index 75396c50d..53ebbeea6 100644 --- a/solutions/typescript/readme.md +++ b/solutions/typescript/readme.md @@ -18,7 +18,7 @@ | [Day 8](/solutions/typescript/2023/08/) | [10.25ms](/solutions/typescript/2023/08/src/p1.ts) | [11.44ms](/solutions/typescript/2023/08/src/p2.ts) | | [Day 9](/solutions/typescript/2023/09/) | [1.57ms](/solutions/typescript/2023/09/src/p1.ts) | [1.62ms](/solutions/typescript/2023/09/src/p2.ts) | | [Day 10](/solutions/typescript/2023/10/) | [68.44ms](/solutions/typescript/2023/10/src/p1.ts) | [1.4s](/solutions/typescript/2023/10/src/p2.ts) | -| Day 11 | - | - | +| [Day 11](/solutions/typescript/2023/11/) | [0ms](/solutions/typescript/2023/11/src/p1.ts) | [0ms](/solutions/typescript/2023/11/src/p2.ts) | | Day 12 | - | - | | Day 13 | - | - | | Day 14 | - | - |