From 835e507816b748da8c37c1ce656c5f36d93668af Mon Sep 17 00:00:00 2001 From: Lewis Dale Date: Mon, 11 Dec 2023 08:58:55 +0000 Subject: [PATCH] Day Eleven --- index.ts | 4 +-- src/day_eleven.test.ts | 27 +++++++++++++++++ src/day_eleven.ts | 66 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 95 insertions(+), 2 deletions(-) create mode 100644 src/day_eleven.test.ts create mode 100644 src/day_eleven.ts diff --git a/index.ts b/index.ts index 3ffc6b4..64fbfdf 100644 --- a/index.ts +++ b/index.ts @@ -1,3 +1,3 @@ -import {runDayNine} from "./src/day_nine"; +import {runDayEleven} from "./src/day_eleven"; -runDayNine(); \ No newline at end of file +runDayEleven(); \ No newline at end of file diff --git a/src/day_eleven.test.ts b/src/day_eleven.test.ts new file mode 100644 index 0000000..955a59c --- /dev/null +++ b/src/day_eleven.test.ts @@ -0,0 +1,27 @@ +import {Observatory} from "./day_eleven"; + +describe('Observatory', () => { + const input = `...#...... +.......#.. +#......... +.......... +......#... +.#........ +.........# +.......... +.......#.. +#...#.....`; + + it('should calculate the shortest path between every galaxy', () => { + const observatory = new Observatory(input); + expect(observatory.shortestPaths).toEqual(82000210); + }); + + it.each([ + [[9, 0], [9, 4], 1_000_004], + [[0, 3], [8, 7], 3_000_012], + ])(`should calculate the distance between two galaxies`, (galaxyOne, galaxyTwo, expectedDistance) => { + const observatory = new Observatory(input); + expect(observatory.distanceBetween(galaxyOne as [number, number], galaxyTwo as [number, number])).toEqual(expectedDistance); + }); +}); \ No newline at end of file diff --git a/src/day_eleven.ts b/src/day_eleven.ts new file mode 100644 index 0000000..9e810c9 --- /dev/null +++ b/src/day_eleven.ts @@ -0,0 +1,66 @@ +import {Range, Seq, Set} from "immutable"; +import fs from "fs"; + +type Position = [number, number]; +type GalaxyPair = [Position, Position]; + +export class Observatory { + private grid: string[][] = []; + private expandedRows: number[] = []; + private expandedColumns: number[] = []; + + constructor(input: string) { + this.grid = input.split('\n').map(line => line.split('')); + + this.expandGrid(); + } + + private expandGrid() { + this.expandedColumns = Range(0, this.grid[0].length).filter(column => this.grid.every(row => row[column] === '.')).toArray(); + this.expandedRows = Range(0, this.grid.length).filter(row => this.grid[row].every(column => column === '.')).toArray(); + } + + public get shortestPaths(): number { + const distances = this.pairs.map(pair => this.distanceBetween(pair[0], pair[1])); + return distances.reduce((sum, distance) => sum + distance, 0); + } + + private get pairs(): GalaxyPair[] { + const galaxies = this.grid.reduce((galaxies, row, rowIndex) => { + row.forEach((galaxy, columnIndex) => { + if (galaxy === '#') { + galaxies.push([rowIndex, columnIndex]); + } + }); + return galaxies; + }, [] as Position[]); + + return galaxies.reduce((pairs, galaxy, index) => { + return pairs.withMutations(pairs => { + galaxies.slice(index + 1).forEach(otherGalaxy => { + pairs.add([galaxy, otherGalaxy]); + }); + }) + }, Set()).toArray(); + } + + private range = (a: number, b: number): Seq.Indexed => { + return Range(Math.min(a, b), Math.max(a, b) + 1); + } + public distanceBetween(galaxyOne: Position, galaxyTwo: Position): number { + const expansion = 999_999; + + const xRange = this.range(galaxyOne[0], galaxyTwo[0]).filter(row => this.expandedRows.includes(row)).toArray().length; + const yRange = this.range(galaxyOne[1], galaxyTwo[1]).filter(column => this.expandedColumns.includes(column)).toArray().length; + + const expansions = expansion * (xRange + yRange) + + return Math.abs(galaxyOne[0] - galaxyTwo[0]) + Math.abs(galaxyOne[1] - galaxyTwo[1]) + expansions; + } +} + +export const runDayEleven = () => { + const input = fs.readFileSync('./inputs/day_eleven_input.txt', 'utf-8').trimEnd(); + const observatory = new Observatory(input); + console.log(`The shortest path between every galaxy is ${observatory.shortestPaths}`); +} \ No newline at end of file