Public
Edited
Nov 11, 2022
1 star
Insert cell
Insert cell
Insert cell
function parse(input) {
const numBags = str => {
const matches = str.match(/(\d+) (.+) /);
return matches ? [matches[2], Number(matches[1])] : null;
};
return Object.fromEntries(
input
.split('\n')
.map(str => str.match(/(.+) bag. contain (no.+|\d+ .+)[.]/).slice(1))
.map(strs => [strs[0], strs[1].split(', ').map(numBags)])
);
}
Insert cell
Insert cell
Insert cell
function addToParents(obj, parent, child) {
const parents = obj[child];
if (parents) {
obj[child] = parents.add(parent);
} else {
obj[child] = new Set([parent]);
}
return obj;
}
Insert cell
Insert cell
function invert(obj) {
let invObj = {};
for (const [parent, children] of Object.entries(obj)) {
for (const child of children) {
if (child) invObj = addToParents(invObj, parent, child[0]);
}
}
return invObj;
}
Insert cell
Insert cell
function findContainers(containers, innerBag) {
const newContainers = containers[innerBag];
let bags = new Set();
if (newContainers) {
for (const bag of newContainers) {
bags = AOC.union(bags.add(bag), findContainers(containers, bag));
}
}
return bags;
}
Insert cell
function part1(input) {
return findContainers(invert(parse(input)), "shiny gold").size;
}
Insert cell
Insert cell
Insert cell
Insert cell
function countContents(bags, bag) {
const contents = bags[bag].filter(Boolean);
let count = 1;
if (contents) {
for (const [b, numBags] of contents) {
count += numBags * countContents(bags, b);
}
}
return count;
}
Insert cell
Insert cell
function part2(input) {
return countContents(parse(input), "shiny gold") - 1;
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more