expeditaet
Version:
Advent of Code Solutions
72 lines (61 loc) • 1.88 kB
text/typescript
import { task } from '@alexaegis/advent-of-code-lib';
import { Direction, Vec2 } from '@alexaegis/advent-of-code-lib/model';
import packageJson from '../package.json';
import { parse } from './parse.js';
export enum Tile {
BUG = '#',
EMTPY = '.',
}
export const bugDie = (adj: Vec2[], map: Tile[][]): boolean => {
return adj.map((a) => map[a.y]?.[a.x]).count((t) => t === Tile.BUG) !== 1;
};
export const infest = (adj: Vec2[], map: Tile[][]): boolean => {
const adjBugs = adj.map((a) => map[a.y]?.[a.x]).count((t) => t === Tile.BUG);
return adjBugs === 1 || adjBugs === 2;
};
export const adjacents = (x: number, y: number): Vec2[] => {
const asCoord = new Vec2(x, y);
return Direction.cardinalDirections
.map((d) => d.add(asCoord))
.filter((c) => c.x >= 0 && c.x < 5 && c.y >= 0 && c.y < 5);
};
export const bio = (map: Tile[][]): number =>
map.flat().reduce((a, t, i) => (t === Tile.BUG ? a + Math.pow(2, i) : a), 0);
export const p1 = (input: string): number => {
let map = parse(input) as Tile[][];
const history = new Set<number>();
let lastBio = bio(map);
history.add(lastBio);
g: for (let gen = 0; gen <= 100_000; gen++) {
const nextGen: Tile[][] = [];
for (let y = 0; y < map.length; y++) {
const row = map[y];
const nextRow: Tile[] = [];
if (row) {
for (let x = 0; x < map.length; x++) {
const tile = row[x];
if (tile) {
const adj = adjacents(x, y);
if (tile === Tile.BUG && bugDie(adj, map)) {
nextRow[x] = Tile.EMTPY;
} else if (tile === Tile.EMTPY && infest(adj, map)) {
nextRow[x] = Tile.BUG;
} else {
nextRow[x] = tile;
}
}
}
}
nextGen[y] = nextRow;
}
map = nextGen;
lastBio = bio(map);
if (history.has(lastBio)) {
break g;
} else {
history.add(lastBio);
}
}
return lastBio;
};
await task(p1, packageJson.aoc); // 13500447 ~3ms