import { bidirectional } from "graphology-shortest-path"; import * as R from "remeda"; import u from "updeep"; import { buildGraph } from "./part1.js"; const findMaxSteam = ( tunnels, graph, minutesLeft, unopened, opened, activeSteam, peeps ) => { console.log({ unopened, activeSteam, minutesLeft }); let next = R.sortBy(peeps, R.prop("eta")); if (next[0].eta > minutesLeft) { return minutesLeft * activeSteam; } const delta = next[0].eta; const location = next[0].destination; const base = delta * activeSteam; minutesLeft -= delta; activeSteam += tunnels[next[0].destination].flow; opened = [...opened, next[0].destination]; next = u.updateIn("1.eta", (eta) => eta - delta, next); const scores = []; let nothing = true; for (const destination of unopened) { const path = bidirectional(graph, location, destination); if (path.length > minutesLeft) { continue; } nothing = false; next = u.updateIn( "0", { location, eta: path.length, destination, }, next ); scores.push( findMaxSteam( tunnels, graph, minutesLeft, unopened.filter((x) => x !== destination), opened, activeSteam, next ) ); } if (nothing) { next = u.updateIn( "0", { location, eta: 999, destination: "END", }, next ); scores.push( findMaxSteam( tunnels, graph, minutesLeft, unopened, opened, activeSteam, next ) ); } return base + Math.max(...scores); }; export default (tunnels) => { const possibilities = Object.keys(tunnels).filter((k) => tunnels[k].flow); const graph = buildGraph(tunnels); return findMaxSteam(tunnels, graph, 26, possibilities, [], 0, [ { destination: "AA", eta: 0 }, { destination: "AA", eta: 0 }, ]); };