diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/2020/day7/aoc.cpp | 31 | ||||
-rw-r--r-- | src/2020/day7/aoc.h | 56 | ||||
-rw-r--r-- | src/2020/day7/input0 | 9 |
3 files changed, 95 insertions, 1 deletions
diff --git a/src/2020/day7/aoc.cpp b/src/2020/day7/aoc.cpp index 2519be1..9ed0f99 100644 --- a/src/2020/day7/aoc.cpp +++ b/src/2020/day7/aoc.cpp @@ -1,4 +1,35 @@ #include "aoc.h" +#include <algorithm> namespace aoc2020 { + +bool find_color(color_bag* bag, line_view color) { + if (bag->color == color) { + return true; + } else { + for (auto& p : bag->bags) { + if (find_color(p.first, color)) { + return true; + } + } + return false; + } +} + +int day7(line_view file, const char* color) { + bag_regulations rs; + per_line(file, [&rs](line_view lv) { + rs.parse(lv); + return true; + }); + + int total{0}; + for (auto& b : rs.regulations) { + if (!(b.second->color == color)) { + total += int(find_color(b.second, color)); + } + } + + return total; } +} // namespace aoc2020 diff --git a/src/2020/day7/aoc.h b/src/2020/day7/aoc.h index 8006657..189237e 100644 --- a/src/2020/day7/aoc.h +++ b/src/2020/day7/aoc.h @@ -1,5 +1,59 @@ #pragma once #include "common.h" +#include <unordered_map> +#include <vector> namespace aoc2020 { -} + +struct color_bag { + line_view color; + std::vector<std::pair<color_bag*, int>> bags; +}; + +struct bag_regulations { + std::unordered_map<line_view, color_bag*> regulations; + + void get_number(const char** pp, int* d) { + const char* p = *pp; + *d = 0; + while (*p >= '0' && *p <= '9') { + *d = *d * 10 + *p - '0'; + p++; + } + *pp = p; + } + + std::pair<color_bag*, int> get_bag(const char* p1, const char* p2) { + int d{0}; + get_number(&p1, &d); + line_view color = {d > 0 ? p1 + 1 : p1, *(p2 - 1) == 's' ? p2 - 5 : p2 - 4}; + color_bag* bag = nullptr; + auto it = regulations.find(color); + if (it == regulations.end()) { + bag = new color_bag{color, {}}; + regulations.insert({color, bag}); + } else { + bag = it->second; + } + return {bag, d}; + } + + void parse(line_view lv) { + const char* p1 = lv.line; + const char* p2 = lv.line + lv.length; + const char* p = lv.contains("contain"); + auto pa1 = get_bag(p1, p - 1); + p1 = p + 8; + p = p1; + while (p < p2) { + if (*p == ',' || *p == '.') { + pa1.first->bags.push_back(get_bag(p1, p)); + p1 = p + 2; + } + p++; + } + } +}; + +int day7(line_view, const char*); +} // namespace aoc2020 diff --git a/src/2020/day7/input0 b/src/2020/day7/input0 new file mode 100644 index 0000000..1cec74f --- /dev/null +++ b/src/2020/day7/input0 @@ -0,0 +1,9 @@ +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. |