Day Eleven

This commit is contained in:
Lewis Dale 2023-12-11 08:58:55 +00:00
parent 376c7a4532
commit 835e507816
3 changed files with 95 additions and 2 deletions

View File

@ -1,3 +1,3 @@
import {runDayNine} from "./src/day_nine";
import {runDayEleven} from "./src/day_eleven";
runDayNine();
runDayEleven();

27
src/day_eleven.test.ts Normal file
View File

@ -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);
});
});

66
src/day_eleven.ts Normal file
View File

@ -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<GalaxyPair>()).toArray();
}
private range = (a: number, b: number): Seq.Indexed<number> => {
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}`);
}