UNPKG

expeditaet

Version:
142 lines (126 loc) 3.85 kB
import { task } from '@alexaegis/advent-of-code-lib'; import { Graph, GraphNode, Vec2, type Vec2String } from '@alexaegis/advent-of-code-lib/model'; import packageJson from '../package.json'; import { TileColor, hexagonalAxialDirections, invertedHexagonalDirections, parse, type HexagonalDirection, } from './parse.function.js'; export const p2 = (input: string): number => { const tilesToFlip = parse(input); const g = new Graph<TileColor, HexagonalDirection>(); const center = new GraphNode<TileColor, HexagonalDirection>( Vec2.ORIGIN.toString(), TileColor.WHITE, ); g.nodes.set(center.key, center); const expandNode = ( g: Graph<TileColor, HexagonalDirection>, node: GraphNode<TileColor, HexagonalDirection>, key?: Vec2String, ) => { const vs = key ?? g.nodes.findKey(node); if (vs) { const atCoord = new Vec2(vs as Vec2String); for (const instruction in invertedHexagonalDirections) { const cursor = atCoord .clone() .addMut(hexagonalAxialDirections[instruction as HexagonalDirection]); // console.log('argare', cursor.toString()); const nextEdge = node.neighbours.getOrAdd( instruction as HexagonalDirection, () => ({ from: node, to: g.nodes.getOrAdd( cursor.toString(), () => new GraphNode<TileColor, HexagonalDirection>( cursor.toString(), TileColor.WHITE, ), ), weight: 1, direction: instruction as HexagonalDirection, }), ); const nextNode = nextEdge.to; const inv = invertedHexagonalDirections[instruction as HexagonalDirection]; nextNode.neighbours.getOrAdd(inv, () => ({ from: nextNode, to: node, weight: 1, direction: inv, })); } } }; /* const expandAllBlack = (g: Graph<TileColor, HexaDirs>) => { for (const [key, node] of g.nodes.entries()) { if (node.value === TileColor.BLACK) { expandNode(g, node, key); } } };*/ const flipTile = ( g: Graph<TileColor, HexagonalDirection>, node: GraphNode<TileColor, HexagonalDirection>, key?: Vec2String, ) => { if (node.value === TileColor.BLACK) { node.setValue(TileColor.WHITE); } else { node.setValue(TileColor.BLACK); expandNode(g, node, key); } }; for (const ttf of tilesToFlip) { let currentNode = center; const cursor = Vec2.ORIGIN.clone(); for (const instruction of ttf) { cursor.addMut(hexagonalAxialDirections[instruction]); const nextEdge = currentNode.neighbours.getOrAdd(instruction, () => ({ from: currentNode, to: g.nodes.getOrAdd( cursor.toString(), () => new GraphNode<TileColor, HexagonalDirection>( cursor.toString(), TileColor.WHITE, ), ), weight: 1, direction: instruction, })); const nextNode = nextEdge.to; const inv = invertedHexagonalDirections[instruction]; nextNode.neighbours.getOrAdd(inv, () => ({ from: nextNode, to: currentNode, weight: 1, direction: inv, })); currentNode = nextNode; } flipTile(g, currentNode, cursor.toString()); } // let blackCount = [...g.nodes.values()].count((node) => node.value === TileColor.BLACK); for (let i = 0; i < 100; i++) { const toFlip = [...g.nodes.entries()].filter(([, node]) => { const blackNeighbours = [...node.neighbours.values()].filter( (neighbour) => neighbour.to.value === TileColor.BLACK, ).length; return node.value === TileColor.BLACK ? blackNeighbours === 0 || blackNeighbours > 2 : blackNeighbours === 2; }); for (const [key, currentNode] of toFlip) { flipTile(g, currentNode, key as Vec2String); } // blackCount = [...g.nodes.values()].count((node) => node.value === TileColor.BLACK); } return [...g.nodes.values()].count((node) => node.value === TileColor.BLACK); }; await task(p2, packageJson.aoc); // 4135 ~391.98ms