|
|
@ -0,0 +1,43 @@ |
|
|
|
#!/bin/node
|
|
|
|
|
|
|
|
const fs = require('fs'); |
|
|
|
|
|
|
|
fs.readFile('input.txt', (err, data) => { |
|
|
|
const rules = data.toString() |
|
|
|
.split('\n') |
|
|
|
.filter(rule => rule.length > 0) |
|
|
|
.map(rule => rule.split(" bags contain ")) |
|
|
|
.map(rule => [rule[0], rule[1].split(', ') |
|
|
|
.filter(line => !line.endsWith('no other bags.')) |
|
|
|
.map(line => line.replace(/ bags?\.?/, '')) |
|
|
|
.map(line => { |
|
|
|
const firstSpaceIndex = line.indexOf(' '); |
|
|
|
return { |
|
|
|
count: parseInt(line.substring(0, firstSpaceIndex)), |
|
|
|
bagColor: line.substring(firstSpaceIndex + 1), |
|
|
|
}; |
|
|
|
})]); |
|
|
|
const ruleMap = {}; |
|
|
|
for (const [containerColor, contents] of rules) { |
|
|
|
ruleMap[containerColor] = contents; |
|
|
|
} |
|
|
|
|
|
|
|
const matchingColors = []; |
|
|
|
let matchingColorsCount; |
|
|
|
do { |
|
|
|
matchingColorsCount = matchingColors.length; |
|
|
|
for (const [containerColor, contents] of rules) { |
|
|
|
if (matchingColors.indexOf(containerColor) < 0 && |
|
|
|
(contents.find(content => content.bagColor === 'shiny gold' || matchingColors.indexOf(content.bagColor) >= 0))) { |
|
|
|
matchingColors.push(containerColor); |
|
|
|
} |
|
|
|
} |
|
|
|
} while (matchingColorsCount !== matchingColors.length); |
|
|
|
|
|
|
|
function countBagsInBag(bagColor, bagCount) { |
|
|
|
const contents = ruleMap[bagColor]; |
|
|
|
return bagCount + bagCount * contents.reduce((sum, content) => sum + countBagsInBag(content.bagColor, content.count), 0); |
|
|
|
} |
|
|
|
|
|
|
|
console.log(matchingColors.length, countBagsInBag('shiny gold', 1) - 1); |
|
|
|
}); |