adventofcode/2022/16/part1.js

93 lines
2.3 KiB
JavaScript

import * as R from "remeda";
import u from "updeep";
import Graph from 'graphology';
import { bidirectional } from 'graphology-shortest-path';
import { combinations, permutations } from "combinatorial-generators";
import { readFile } from "../05/part1.js";
const parseLine = (line) => {
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)
}]
}
const readInput = (...args) =>
R.pipe(
readFile(...args),
(lines) => lines.split("\n"),
R.compact, // remove last line
R.map(parseLine),
Object.fromEntries,
);
export const puzzleInput = readInput(import.meta.url, "input");
export const sample = readInput(import.meta.url, "sample");
function finalSteam(tunnels, graph, minutesLeft, possibilities, location = 'AA', activeSteam = 0) {
//console.log(minutesLeft, totalSteam, itinary);
if (minutesLeft <= 0) return 0;
if (possibilities.length === 0) return minutesLeft * activeSteam;
let scores = [];
for ( const next of possibilities ) {
const path = bidirectional(graph, location, next);
//console.log(path);
let time = path.length;
if (time >= minutesLeft) {
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
)
)
}
}
return Math.max( ...scores );
}
export const buildGraph = tunnels => {
const graph = new Graph();
Object.keys(tunnels).forEach(x => graph.addNode(x));
Object.entries(tunnels).forEach(([location, { exits }]) => {
exits.forEach(exit => graph.addEdge(location, exit));
});
return graph;
};
export default (tunnels) => {
const possibilities =
Object.keys(tunnels).filter(
k => tunnels[k].flow
);
const graph = buildGraph(tunnels);
return finalSteam(tunnels, graph, 30, possibilities, 'AA', 0, 0)
};