adventofcode/2022/16/part1.js

99 lines
2.2 KiB
JavaScript
Raw Normal View History

2022-12-18 22:13:07 +00:00
import * as R from "remeda";
import u from "updeep";
2023-11-30 15:13:16 +00:00
import Graph from "graphology";
import { bidirectional } from "graphology-shortest-path";
2022-12-18 23:42:55 +00:00
2022-12-25 22:09:27 +00:00
import { combinations, permutations } from "combinatorial-generators";
2022-12-18 23:42:55 +00:00
2022-12-18 22:13:07 +00:00
import { readFile } from "../05/part1.js";
const parseLine = (line) => {
2023-11-30 15:13:16 +00:00
const { groups } = line.match(
/Valve (?<valve>..).*flow rate=(?<flow>\d+).*valves? (?<exits>.*)/
);
return [
groups.valve,
{
exits: groups.exits.split(",").map((x) => x.trim()),
flow: parseInt(groups.flow),
},
];
};
2022-12-18 22:13:07 +00:00
const readInput = (...args) =>
2023-11-30 15:13:16 +00:00
R.pipe(
readFile(...args),
(lines) => lines.split("\n"),
R.compact, // remove last line
R.map(parseLine),
Object.fromEntries
);
2022-12-18 22:13:07 +00:00
export const puzzleInput = readInput(import.meta.url, "input");
export const sample = readInput(import.meta.url, "sample");
2023-11-30 15:13:16 +00:00
function finalSteam(
tunnels,
graph,
minutesLeft,
possibilities,
location = "AA",
activeSteam = 0
) {
//console.log(minutesLeft, totalSteam, itinary);
if (minutesLeft <= 0) return 0;
2022-12-18 22:13:07 +00:00
2023-11-30 15:13:16 +00:00
if (possibilities.length === 0) return minutesLeft * activeSteam;
2022-12-18 22:13:07 +00:00
2023-11-30 15:13:16 +00:00
let scores = [];
2022-12-18 22:13:07 +00:00
2023-11-30 15:13:16 +00:00
for (const next of possibilities) {
const path = bidirectional(graph, location, next);
2022-12-18 22:13:07 +00:00
2022-12-25 22:09:27 +00:00
//console.log(path);
let time = path.length;
if (time >= minutesLeft) {
2023-11-30 15:13:16 +00:00
scores.push(minutesLeft * activeSteam);
} else {
//console.log({totalSteam, time, activeSteam});
let ts = time * activeSteam;
let as = activeSteam + tunnels[next].flow;
scores.push(
ts +
finalSteam(
tunnels,
graph,
minutesLeft - time,
possibilities.filter((x) => x !== next),
next,
as
)
);
2022-12-18 22:13:07 +00:00
}
2023-11-30 15:13:16 +00:00
}
2022-12-18 22:13:07 +00:00
2023-11-30 15:13:16 +00:00
return Math.max(...scores);
2022-12-18 22:13:07 +00:00
}
2023-11-30 15:13:16 +00:00
export const buildGraph = (tunnels) => {
const graph = new Graph();
Object.keys(tunnels).forEach((x) => graph.addNode(x));
2022-12-25 22:09:27 +00:00
2023-11-30 15:13:16 +00:00
Object.entries(tunnels).forEach(([location, { exits }]) => {
exits.forEach((exit) => graph.addEdge(location, exit));
});
2022-12-25 22:09:27 +00:00
2023-11-30 15:13:16 +00:00
return graph;
2022-12-25 22:09:27 +00:00
};
2022-12-18 22:13:07 +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-18 23:42:55 +00:00
2023-11-30 15:13:16 +00:00
const graph = buildGraph(tunnels);
2022-12-18 23:42:55 +00:00
2023-11-30 15:13:16 +00:00
return finalSteam(tunnels, graph, 30, possibilities, "AA", 0, 0);
2022-12-18 22:13:07 +00:00
};