aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/2015/day19/aoc.cpp12
-rw-r--r--src/2015/day19/aoc.h70
-rw-r--r--test/test_2015.cpp4
3 files changed, 85 insertions, 1 deletions
diff --git a/src/2015/day19/aoc.cpp b/src/2015/day19/aoc.cpp
index 1b3ee2a..b665871 100644
--- a/src/2015/day19/aoc.cpp
+++ b/src/2015/day19/aoc.cpp
@@ -1,4 +1,16 @@
#include "aoc.h"
namespace aoc2015 {
+
+int day19(line_view file) {
+ molecule m;
+ per_line(file, [&m](line_view lv) {
+ m.parse(lv);
+ return true;
+ });
+ std::map<int, std::vector<molecule::change>> changes;
+ m.check(changes);
+ return m.distinct(changes);
}
+
+} // namespace aoc2015
diff --git a/src/2015/day19/aoc.h b/src/2015/day19/aoc.h
index b1ba95c..b357ab1 100644
--- a/src/2015/day19/aoc.h
+++ b/src/2015/day19/aoc.h
@@ -1,6 +1,74 @@
#pragma once
#include "common.h"
+#include <map>
+#include <vector>
namespace aoc2015 {
-}
+
+struct replacement {
+ line_view from;
+ line_view to;
+};
+
+struct molecule {
+ std::vector<replacement> replacements;
+ line_view original;
+
+ struct change {
+ size_t i;
+ replacement c;
+ };
+
+ void check(size_t i, replacement r, std::map<int, std::vector<change>>& vr) const noexcept {
+ const char* p1 = original.line;
+ const char* p2 = original.line + original.length;
+ do {
+ line_view lv = line_view{p1, p2};
+ const char* p = lv.contains(r.from);
+ // std::cout << lv << ": " << r.from << " -> " << r.to << std::endl;
+ if (p != nullptr) {
+ vr[r.to.length - r.from.length].push_back({i, {line_view{p, r.from.length}, r.to}});
+ p1 = p + r.from.length;
+ } else {
+ break;
+ }
+ } while (p1 < p2);
+ }
+
+ void check(std::map<int, std::vector<change>>& vr) const noexcept {
+ for (size_t i = 0; i < replacements.size(); i++) {
+ check(i, replacements[i], vr);
+ }
+ }
+
+ int distinct(const std::vector<change>& vc) const noexcept {
+ for (auto& c : vc) {
+ std::cout << c.i << ": " << original << " " << (c.c.from.line - original.line) << " " << c.c.to << std::endl;
+ }
+ return 0;
+ }
+
+ int distinct(const std::map<int, std::vector<change>>& vr) const noexcept {
+ int d{0};
+ for (auto& kv : vr) {
+ d += distinct(kv.second);
+ }
+ return d;
+ }
+
+ void parse(line_view lv) {
+ const char* p = lv.contains("=>");
+ if (p != nullptr) {
+ replacements.push_back({{lv.line, p - 1}, {p + 3, lv.line + lv.length - 1}});
+ } else {
+ if (lv.length > 1) {
+ original = {lv.line, lv.line + lv.length - 1};
+ }
+ }
+ }
+};
+
+int day19(line_view);
+
+} // namespace aoc2015
diff --git a/test/test_2015.cpp b/test/test_2015.cpp
index 39b4980..ef76a14 100644
--- a/test/test_2015.cpp
+++ b/test/test_2015.cpp
@@ -87,6 +87,7 @@ TEST_CASE("Doesn't He Have Intern-Elves For This?", "[day5]") {
}
TEST_CASE("Probably a Fire Hazard", "[day6]") {
+ /*
aoc2015::grid<aoc2015::Bit, 1000> grid;
grid.turn_on({0, 0}, {0, 999});
REQUIRE(grid.store_.count() == 1000);
@@ -94,6 +95,7 @@ TEST_CASE("Probably a Fire Hazard", "[day6]") {
aoc2015::grid<int8_t, 1000> grid2;
grid2.toggle({0, 0}, {0, 999});
REQUIRE(grid2.store_.count() == 2000);
+ */
line_view lv = load_file("../src/2015/day6/input");
auto p = aoc2015::day6(lv);
@@ -200,4 +202,6 @@ TEST_CASE("Like a GIF For Your Yard", "[day18]") {
TEST_CASE("Medicine for Rudolph", "[day19]") {
// line_view lv = load_file("../src/2015/day19/input");
+ line_view lv = line_view{"H => HO\nH => OH\nO => HH\n\nHOH\n"};
+ aoc2015::day19(lv);
}