adventofcode/2022/16/part2.js

106 lines
1.9 KiB
JavaScript
Raw Normal View History

2023-11-30 15:13:16 +00:00
import { bidirectional } from "graphology-shortest-path";
2022-12-18 22:13:07 +00:00
import * as R from "remeda";
2023-11-30 15:13:16 +00:00
import u from "updeep";
2022-12-18 22:13:07 +00:00
2023-11-30 15:13:16 +00:00
import { buildGraph } from "./part1.js";
2022-12-18 22:13:07 +00:00
2023-11-30 15:13:16 +00:00
const findMaxSteam = (
tunnels,
graph,
minutesLeft,
unopened,
opened,
activeSteam,
peeps
) => {
console.log({ unopened, activeSteam, minutesLeft });
2023-01-02 16:02:06 +00:00
2023-11-30 15:13:16 +00:00
let next = R.sortBy(peeps, R.prop("eta"));
2023-01-02 16:02:06 +00:00
2023-11-30 15:13:16 +00:00
if (next[0].eta > minutesLeft) {
return minutesLeft * activeSteam;
}
2023-01-02 16:02:06 +00:00
2023-11-30 15:13:16 +00:00
const delta = next[0].eta;
const location = next[0].destination;
2023-01-02 16:02:06 +00:00
2023-11-30 15:13:16 +00:00
const base = delta * activeSteam;
minutesLeft -= delta;
2023-11-30 15:10:58 +00:00
2023-11-30 15:13:16 +00:00
activeSteam += tunnels[next[0].destination].flow;
opened = [...opened, next[0].destination];
2023-01-02 16:02:06 +00:00
2023-11-30 15:13:16 +00:00
next = u.updateIn("1.eta", (eta) => eta - delta, next);
2022-12-25 22:09:27 +00:00
2023-11-30 15:13:16 +00:00
const scores = [];
2022-12-25 22:09:27 +00:00
2023-11-30 15:13:16 +00:00
let nothing = true;
for (const destination of unopened) {
const path = bidirectional(graph, location, destination);
2022-12-25 22:09:27 +00:00
2023-11-30 15:13:16 +00:00
if (path.length > minutesLeft) {
continue;
2022-12-25 22:09:27 +00:00
}
2023-11-30 15:13:16 +00:00
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);
};
2022-12-25 22:09:27 +00:00
export default (tunnels) => {
2023-11-30 15:13:16 +00:00
const possibilities = Object.keys(tunnels).filter((k) => tunnels[k].flow);
2022-12-25 22:09:27 +00:00
2023-11-30 15:13:16 +00:00
const graph = buildGraph(tunnels);
2022-12-25 22:09:27 +00:00
2023-11-30 15:13:16 +00:00
return findMaxSteam(tunnels, graph, 26, possibilities, [], 0, [
{ destination: "AA", eta: 0 },
{ destination: "AA", eta: 0 },
]);
2022-12-25 22:09:27 +00:00
};