UNPKG

expeditaet

Version:
66 lines (59 loc) 1.96 kB
import { task } from '@alexaegis/advent-of-code-lib'; import { Graph, GraphNode } from '@alexaegis/advent-of-code-lib/model'; import packageJson from '../package.json'; const pathContains = ( path: GraphNode<string, number>[], node: GraphNode<string, number>, atMost = 1, ): boolean => { return path.count((pathNode) => pathNode.value === node.value) >= atMost; }; const getPaths = ( current: GraphNode<string, number>, until: (node: GraphNode<string, number>) => boolean, allPaths: GraphNode<string, number>[][], visitTwice: string | undefined, path: GraphNode<string, number>[] = [], ): void => { path.push(current); if (until(current)) { allPaths.push(path); return; } for (const neighbour of current) { if ( neighbour.to.value === 'start' || (neighbour.to.value.isLowerCase() && pathContains(path, neighbour.to, neighbour.to.value === visitTwice ? 2 : 1)) ) { continue; } getPaths(neighbour.to, until, allPaths, visitTwice, [...path]); } }; /** * Find all unique paths from start to end * @param input * @returns */ export const p2 = (input: string): number => { const valueEdges = input.lines().map((line) => { const [from, to] = line.splitIntoStringPair('-'); return { from, to }; }); const graph = Graph.fromUniqueValueEdges<string>(valueEdges, (t) => t, true); const start = graph.getNode('start'); if (!start) { throw new Error('No start node!'); } const smallCaves = [...graph.nodes.values()].filter((node) => node.value.isLowerCase()); const allPaths: GraphNode<string, number>[][] = smallCaves.flatMap((smallCave) => { const paths: GraphNode<string, number>[][] = []; getPaths(start, (node) => node.value === 'end', paths, smallCave.value); return paths; }); const renderedPaths = allPaths.map((p) => p.map((e) => e.value).join(',')); const uniqueRenderedPaths = renderedPaths.unique(); return uniqueRenderedPaths.length; }; await task(p2, packageJson.aoc); // 98441 ~42s