diff --git a/2020/day7/day7.js b/2020/day7/day7.js new file mode 100755 index 0000000..89c6f87 --- /dev/null +++ b/2020/day7/day7.js @@ -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); +});