advent-of-code/2022/16/index.js

88 lines
2.1 KiB
JavaScript

const fs = require('fs/promises');
const sum = (arr) => arr.reduce((total, num) => total+num, 0);
const arrayOfLength = n => Array.from(Array(n).keys()).map(() => {});
const createNode = (str) => {
const stats = str.match(/Valve ([A-Z]+) has flow rate=([\d]+); tunnels? leads? to valves? (.*)$/);
if(!stats) {
console.log("Bad line? : ", str);
return;
}
const id = stats[1];
const rate = stats[2];
const edges = stats[3].split(', ');
return {
id,
rate,
edges,
};
};
const main = async () => {
const input = (await fs.readFile("./input.txt", 'utf8')).split("\n").slice(0, -1).sort();
const nodesById = {};
for(const row of input) {
const node = createNode(row);
if(!node) continue;
nodesById[node.id] = node;
}
const nodesByRate = Object.values(nodesById).sort((a, b) => b.rate - a.rate).filter(n => n.rate > 0);
console.log("nodes by rate: ", nodesByRate);
const findEachOptimalPath = (node, queue = [], visited = {}, length = 0) => {
visited[node.id] = length;
for(const edge of node.edges) {
const neighbor = nodesById[edge];
if(typeof visited[neighbor.id] === "undefined") {
queue.push(() => findEachOptimalPath(neighbor, queue, visited, length + 1));
}
};
if(queue.length) {
return queue.shift()();
}
return visited;
};
const valvePossibilities = Object.values(nodesById).reduce((possibilities, node) => {
possibilities[node.id] = findEachOptimalPath(node);
return possibilities;
}, {});
let best = 0;
const plan = (node, value, opened = {}, time = 30) => {
if(node.rate > 0 && time > 0) {
time = time - 1;
opened[node.id] = true;
value = value + time * node.rate;
}
if(value > best) {
best = value;
console.log(`${best} is better!`);
}
const distances = valvePossibilities[node.id];
for(const next of nodesByRate.filter(n => !opened[n.id])) {
const distance = distances[next.id];
if(time > distance + 1) {
plan(next, value, {...opened}, time - distances[next.id]);
}
}
};
plan(nodesById["AA"], 0);
console.log("Answer is: ", best);
}
main();