adventofcode/2022/16/part2.js

106 lines
1.9 KiB
JavaScript

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 },
]);
};