Day Eleven
This commit is contained in:
parent
376c7a4532
commit
835e507816
4
index.ts
4
index.ts
@ -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
27
src/day_eleven.test.ts
Normal 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
66
src/day_eleven.ts
Normal 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}`);
|
||||
}
|
Loading…
Reference in New Issue
Block a user