jsadvent/solutions/2019/6.js
2020-12-10 02:33:00 -06:00

70 lines
1.6 KiB
JavaScript

const { Glib, Maps, Sets, Vector, twodee } = require('../../lib');
const parse = (input) => {
const pairs = Glib.fromLines(input).map((i) => i.split(')')).array;
const parents = pairs.glib.map((pair) => pair.safeReverse()).toMap();
const children = pairs.glib.toMapSet();
const points = new Map(
pairs.glib
.flatMap((i) => i)
.unique()
.map((point) => [
point,
{
children: children.get(point),
parent: parents.get(point),
},
]),
);
return points;
};
const count = (map, source = 'COM', depth = 0n) => {
return (
(map.get(source).children || []).glib
.map((name) => count(map, name, depth + 1n))
.sum() + depth
);
};
const distance = (source, destination, info) => {
let current = source;
let distance = 0n;
while (current !== destination && current !== 'COM') {
distance++;
current = info.get(current).parent;
}
if (current !== destination) {
throw new Error('no link (toward COM)');
}
return distance;
};
const allParents = (source, input) =>
new Glib(
(function*() {
let current = source;
while (current !== 'COM') {
current = input.get(current).parent;
yield current;
}
})(),
);
module.exports = {
'1': (input) => count(parse(input), 'COM'),
2: (input) => {
input = parse(input);
return (
Sets.and(allParents('YOU', input).set, allParents('SAN', input).set)
.glib.map(
(midpoint) =>
distance('YOU', midpoint, input) + distance('SAN', midpoint, input),
)
.min() - 2n
);
},
};