adventofcode/2021/12/part2.mjs

61 lines
1.5 KiB
JavaScript
Raw Normal View History

2021-12-12 18:19:18 +00:00
import fs from "fs-extra";
import fp from "lodash/fp.js";
import _ from "lodash";
2021-12-12 18:24:41 +00:00
import * as p1 from "./part1.mjs";
2021-12-12 18:19:18 +00:00
export function solution(graph) {
let paths = 0;
2021-12-12 18:24:41 +00:00
graph.forEachNode((node) => {
graph.setNodeAttribute(node, "nbrVisits", 0);
});
2021-12-12 18:19:18 +00:00
2021-12-12 18:24:41 +00:00
const left = [{ graph, where: "start" }];
2021-12-12 18:19:18 +00:00
2021-12-12 18:24:41 +00:00
while (left.length > 0) {
2021-12-12 18:19:18 +00:00
const position = left.shift();
2021-12-12 18:24:41 +00:00
if (position.where === "end") {
2021-12-12 18:19:18 +00:00
paths++;
continue;
}
2021-12-12 18:24:41 +00:00
const canVisit = (graph, node) => {
if (node === "start") return false;
if (node === node.toUpperCase()) return true;
const nbrVisits = graph.getNodeAttribute(node, "nbrVisits");
2021-12-12 18:19:18 +00:00
2021-12-12 18:24:41 +00:00
if (nbrVisits === 0) return true;
if (nbrVisits > 1) return false;
return !graph.hasAttribute("revisited");
};
2021-12-12 18:19:18 +00:00
2021-12-12 18:24:41 +00:00
for (const n of position.graph
.neighbors(position.where)
.filter((n) => canVisit(position.graph, n))) {
2021-12-12 18:19:18 +00:00
let newGraph = position.graph;
2021-12-12 18:24:41 +00:00
if (n === n.toLowerCase()) {
2021-12-12 18:19:18 +00:00
newGraph = newGraph.copy();
2021-12-12 18:24:41 +00:00
newGraph.updateNodeAttribute(
n,
"nbrVisits",
fp.add(1)
2021-12-12 18:19:18 +00:00
);
2021-12-12 18:24:41 +00:00
if (newGraph.getNodeAttribute(n, "nbrVisits") === 2) {
newGraph.setAttribute("revisited", n);
2021-12-12 18:19:18 +00:00
}
}
left.unshift({
graph: newGraph,
where: n,
});
}
}
return paths;
}