71 lines
1.8 KiB
JavaScript
71 lines
1.8 KiB
JavaScript
const { Glib, Maps } = require('../../lib');
|
|
|
|
const parse = (input) =>
|
|
Glib.fromLines(input).map((line) => {
|
|
const [color, heldString] = line.split(' bags contain ');
|
|
const children = [];
|
|
|
|
if (heldString !== 'no other bags.') {
|
|
const helds = heldString.split(', ');
|
|
for (const held of helds) {
|
|
const [heldDef] = held.split(' bag');
|
|
const [heldNum, ...heldColorArr] = heldDef.split(' ');
|
|
const heldColor = heldColorArr.join(' ');
|
|
children.push({
|
|
count: BigInt(heldNum),
|
|
color: heldColor,
|
|
});
|
|
}
|
|
}
|
|
|
|
return { color, children };
|
|
});
|
|
|
|
const parseChildren = (input) =>
|
|
parse(input).reduce((map, { color, children }) => {
|
|
map.set(color, children);
|
|
return map;
|
|
}, new Map());
|
|
|
|
const parseParents = (input) =>
|
|
parse(input).reduce((map, { color: parentColor, children }) => {
|
|
for (const { color } of children) {
|
|
let parent;
|
|
map.set(color, (parent = map.get(color) || new Set()));
|
|
parent.add(parentColor);
|
|
}
|
|
return map;
|
|
}, new Map());
|
|
|
|
const childrenCount = (start, graph) => {
|
|
const children = graph.get(start) || [];
|
|
let count = BigInt(0);
|
|
for (const child of children) {
|
|
count += child.count;
|
|
count += childrenCount(child.color, graph) * child.count;
|
|
}
|
|
|
|
return count;
|
|
};
|
|
|
|
module.exports = {
|
|
'1': (input) => {
|
|
const parents = parseParents(input);
|
|
|
|
const found = new Set(parents.get('shiny gold'));
|
|
let lastCount = 0;
|
|
while (lastCount !== found.size) {
|
|
lastCount = found.size;
|
|
for (const color of found) {
|
|
for (const addedColor of parents.get(color) || []) {
|
|
found.add(addedColor);
|
|
}
|
|
}
|
|
}
|
|
return lastCount;
|
|
},
|
|
'2': (input) => {
|
|
return childrenCount('shiny gold', parseChildren(input));
|
|
},
|
|
};
|