mirror of
https://github.com/HenkKalkwater/aoc-2020
synced 2025-09-05 09:52:44 +00:00
Added day 7
This commit is contained in:
parent
4f17dbae8e
commit
a321a1a7b4
4 changed files with 727 additions and 2 deletions
|
@ -13,6 +13,7 @@ import day3;
|
|||
import day4;
|
||||
import day5;
|
||||
import day6;
|
||||
import day7;
|
||||
import dayutil;
|
||||
|
||||
immutable string progName = "aoc-2020";
|
||||
|
@ -24,6 +25,7 @@ Variant function(int, File, bool, string[])[] programs = [
|
|||
&day4.run,
|
||||
&day5.run,
|
||||
&day6.run,
|
||||
&day7.run,
|
||||
];
|
||||
|
||||
void printUsage(string name) {
|
||||
|
|
|
@ -43,7 +43,7 @@ int part1(SortedRange!(int[]) numbers, int target) {
|
|||
|
||||
unittest {
|
||||
auto numbers = [1721, 979, 366, 299, 675, 1456].sort;
|
||||
assert(part1(numbers) == 514579);
|
||||
assert(part1(numbers, 2020) == 514579);
|
||||
}
|
||||
|
||||
int part2(SortedRange!(int[]) numbers, int target) {
|
||||
|
@ -63,5 +63,5 @@ exit:
|
|||
|
||||
unittest {
|
||||
auto numbers = [1721, 979, 366, 299, 675, 1456].sort;
|
||||
assert(part2(numbers) == 241861950);
|
||||
assert(part2(numbers, 2020) == 241861950);
|
||||
}
|
||||
|
|
129
source/day7.d
Normal file
129
source/day7.d
Normal file
|
@ -0,0 +1,129 @@
|
|||
import std.algorithm;
|
||||
import std.array;
|
||||
import std.format;
|
||||
import std.range;
|
||||
import std.stdio;
|
||||
import std.string;
|
||||
import std.traits;
|
||||
import std.variant;
|
||||
|
||||
import dayutil;
|
||||
|
||||
alias Colour = size_t;
|
||||
|
||||
Variant run(int part, File input, bool bigboy, string[] args) {
|
||||
BagNode[][Colour] rules;
|
||||
input.byLineCopy.each!(x => x.parseAndAddRule(rules));
|
||||
|
||||
Variant result = parts!size_t(part,
|
||||
() => part1(rules),
|
||||
() => part2(rules));
|
||||
return result;
|
||||
}
|
||||
|
||||
size_t part1(BagNode[][Colour] rules) {
|
||||
Colour result = 0;
|
||||
foreach(Colour colour; rules.byKey()) {
|
||||
if (eventuallyContains(rules, rules[colour], colourCode("shiny gold"))) {
|
||||
result++;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
size_t part2(BagNode[][Colour] rules) {
|
||||
return countContaining(rules, rules[colourCode("shiny gold")]);
|
||||
}
|
||||
|
||||
size_t[string] colourCodeMap;
|
||||
size_t index = 0;
|
||||
size_t colourCode(string colour) {
|
||||
return colourCodeMap.require(colour, index++);
|
||||
}
|
||||
|
||||
struct BagNode {
|
||||
this(string colour, size_t count) {
|
||||
this.colour = colourCode(colour);
|
||||
this.count = count;
|
||||
}
|
||||
Colour colour;
|
||||
size_t count = 0;
|
||||
}
|
||||
|
||||
void parseAndAddRule(string rule, ref BagNode[][size_t] ruleMap) {
|
||||
auto splitRes = rule.splitter(" bags contain ").array;
|
||||
size_t key = colourCode(splitRes[0]);
|
||||
BagNode[] value = [];
|
||||
if (splitRes[1] != "no other bags.") {
|
||||
value = splitRes[1].splitter(", ").map!((x) {
|
||||
string colour;
|
||||
size_t count;
|
||||
x.splitter(" bag").array[0].formattedRead!"%d %s"(count, colour);
|
||||
return BagNode(colour, count);
|
||||
}).array;
|
||||
}
|
||||
ruleMap[key] = value;
|
||||
}
|
||||
|
||||
bool eventuallyContains(BagNode[][Colour] colourMap, BagNode[] nodes, Colour colour) {
|
||||
foreach(BagNode node; nodes) {
|
||||
if (node.colour == colour) {
|
||||
return true;
|
||||
} else {
|
||||
if (eventuallyContains(colourMap, colourMap[node.colour], colour)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t countContaining(BagNode[][Colour] colourMap, BagNode[] children) {
|
||||
size_t total = 0;
|
||||
//writeln("Recursing into node with ", children.length, " children");
|
||||
|
||||
foreach(BagNode node; children) {
|
||||
total += node.count * (1 + countContaining(colourMap, colourMap[node.colour]));
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
unittest {
|
||||
string input = q"EOS
|
||||
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.
|
||||
EOS";
|
||||
BagNode[][size_t] testRules;
|
||||
input.lineSplitter.each!(x => x.parseAndAddRule(testRules));
|
||||
assert(testRules[colourCode("light red")] == [BagNode("bright white", 1), BagNode("muted yellow", 2)]);
|
||||
assert(part1(testRules) == 4);
|
||||
|
||||
assert(countContaining(testRules, testRules[colourCode("faded blue")]) == 0);
|
||||
assert(countContaining(testRules, testRules[colourCode("vibrant plum")]) == 11);
|
||||
}
|
||||
|
||||
unittest {
|
||||
string input = q"EOS
|
||||
shiny gold bags contain 2 dark red bags.
|
||||
dark red bags contain 2 dark orange bags.
|
||||
dark orange bags contain 2 dark yellow bags.
|
||||
dark yellow bags contain 2 dark green bags.
|
||||
dark green bags contain 2 dark blue bags.
|
||||
dark blue bags contain 2 dark violet bags.
|
||||
dark violet bags contain no other bags.
|
||||
EOS";
|
||||
|
||||
BagNode[][size_t] testRules;
|
||||
input.lineSplitter.each!(x => x.parseAndAddRule(testRules));
|
||||
|
||||
size_t count = part2(testRules);
|
||||
assert(count == 126);
|
||||
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue