aoc2020/day7/part1/main.d

65 lines
2.1 KiB
D
Raw Normal View History

2020-12-08 11:19:38 +01:00
import std;
void main()
{
readText("input").calculateNumberOfContainingBagsTranisitively("shiny gold").writeln;
}
auto calculateNumberOfContainingBagsTranisitively(string rules, string color)
{
return rules.calculateContainingBagsTranisitively(color).byKey.count;
}
auto calculateContainingBagsTranisitively(string rules, string color)
{
return rules.parseRules.calculateContainingBagsTranisitively(color);
}
void[0][string] calculateContainingBagsTranisitively(string[][string] containedInMap, string color)
{
string[]* containingBags = (color in containedInMap);
if (!containingBags || (*containingBags).length == 0)
{
return null;
}
void[0][string] result;
foreach (bag; *containingBags)
{
result[bag] = [];
containedInMap.calculateContainingBagsTranisitively(bag)
.byKey.each!((containingBag) => result[containingBag] = []);
}
return result;
}
auto parseRules(string rules)
{
string[][string] containedInMap;
rules.splitter("\n").filter!(not!empty)
.each!((rule) {
auto spec = rule.split(" bags contain ");
auto containingBag = spec[0];
spec[1].splitter(", ").filter!(it => it != "no other bags.")
.map!(bagSpec => bagSpec.matchFirst(r"(\d+) (.+) (bag|bags)\.*")[2])
.each!(bag => containedInMap.update(bag, {
return [containingBag];
}, (ref string[] old) { return old ~ [containingBag]; }));
});
return containedInMap;
}
unittest
{
auto input = `light red bags contain 1 bright white bag, 2 muted yellow bags.
dark orange bags contain 3 bright white bags, 4 muted yellow bags.
bright white bags contain 1 shiny gold bag.
muted yellow bags contain 2 shiny gold bags, 9 faded blue bags.
shiny gold bags contain 1 dark olive bag, 2 vibrant plum bags.
dark olive bags contain 3 faded blue bags, 4 dotted black bags.
vibrant plum bags contain 5 faded blue bags, 6 dotted black bags.
faded blue bags contain no other bags.
dotted black bags contain no other bags.`;
assert(input.calculateNumberOfContainingBagsTranisitively("shiny gold") == 4);
}