aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/2020/day7/aoc.cpp31
-rw-r--r--src/2020/day7/aoc.h56
-rw-r--r--src/2020/day7/input09
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.