advent-of-code-2023/src/day_eleven.ts

66 lines
2.2 KiB
TypeScript
Raw Normal View History

2023-12-11 08:58:55 +00:00
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}`);
}