aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKai WU <kaiwu2004@gmail.com>2022-03-17 23:13:18 +0800
committerKai WU <kaiwu2004@gmail.com>2022-03-17 23:13:18 +0800
commit2f44c63c1d31e20fbb848568a53c09823f54a329 (patch)
treebf61fb3eb3841068baf5b79e3af1e4e5c9b1dc83
parent29b341616a344ee89a776b3031353643b33afb58 (diff)
downloadadvent-of-code-2f44c63c1d31e20fbb848568a53c09823f54a329.tar.gz
advent-of-code-2f44c63c1d31e20fbb848568a53c09823f54a329.zip
cache compute
-rw-r--r--src/2015/day7/aoc.cpp9
-rw-r--r--src/2015/day7/aoc.h38
-rw-r--r--test/test_2015.cpp6
3 files changed, 39 insertions, 14 deletions
diff --git a/src/2015/day7/aoc.cpp b/src/2015/day7/aoc.cpp
index 1c33c66..b09e317 100644
--- a/src/2015/day7/aoc.cpp
+++ b/src/2015/day7/aoc.cpp
@@ -2,4 +2,13 @@
namespace aoc2015 {
+result day7(line_view file, const char* wire) {
+ cals cs;
+ per_line(file, [&cs](line_view lv) {
+ cs.parse(lv);
+ return true;
+ });
+ return cs.compute(wire);
}
+
+} // namespace aoc2015
diff --git a/src/2015/day7/aoc.h b/src/2015/day7/aoc.h
index e161166..4299fcb 100644
--- a/src/2015/day7/aoc.h
+++ b/src/2015/day7/aoc.h
@@ -50,7 +50,7 @@ struct result {
};
struct cals {
- std::map<line_view, std::function<result()>> calls;
+ std::map<line_view, std::pair<std::function<result()>, result>> calls;
bool is_value(line_view v, uint16_t* x) const noexcept {
const char* p = v.line;
@@ -65,44 +65,52 @@ struct cals {
return true;
}
- result compute(line_view w) const noexcept {
- // std::cout << "compute " << w << std::endl;
+ result compute(line_view w) {
uint16_t x = 0;
if (is_value(w, &x)) {
return {result::c_value, x};
} else {
auto it = calls.find(w);
- return it != calls.end() ? it->second() : result{result::c_unknown, 0};
+ if (it != calls.end()) {
+ auto& r = it->second.second;
+ if (r.type == result::c_unknown) {
+ // std::cout << "compute " << w << std::endl;
+ auto& f = it->second.first;
+ r = f();
+ }
+ return r;
+ }
+ return {result::c_unknown, 0};
}
}
- std::function<result()> op_and(line_view& x, line_view& y) const noexcept {
+ std::function<result()> op_and(line_view& x, line_view& y) {
return [&x, &y, this]() -> result { return compute(x).op_and(compute(y)); };
}
- std::function<result()> op_or(line_view& x, line_view& y) const noexcept {
+ std::function<result()> op_or(line_view& x, line_view& y) {
return [&x, &y, this]() -> result { return compute(x).op_or(compute(y)); };
}
- std::function<result()> op_leftshift(line_view& x, line_view& y) const noexcept {
+ std::function<result()> op_leftshift(line_view& x, line_view& y) {
return [&x, &y, this]() -> result { return compute(x).op_leftshift(compute(y)); };
}
- std::function<result()> op_rightshift(line_view& x, line_view& y) const noexcept {
+ std::function<result()> op_rightshift(line_view& x, line_view& y) {
return [&x, &y, this]() -> result { return compute(x).op_rightshift(compute(y)); };
}
- std::function<result()> op_not(line_view& x, line_view& y) const noexcept {
+ std::function<result()> op_not(line_view& x, line_view& y) {
return [&x, this]() -> result { return compute(x).op_not(); };
}
- std::function<result()> op_value(line_view& x, line_view& y) const noexcept {
+ std::function<result()> op_value(line_view& x, line_view& y) {
return [&x, this]() -> result { return compute(x); };
}
- std::function<result()> parse(line_view line, line_view* x, line_view* y, line_view* w) const noexcept {
+ std::function<result()> parse(line_view line, line_view* x, line_view* y, line_view* w) {
static struct _ {
- std::function<result()> (cals::*op)(line_view&, line_view&) const noexcept;
+ std::function<result()> (cals::*op)(line_view&, line_view&);
const char* label;
} ops[] = {
{&cals::op_and, "AND"},
@@ -111,7 +119,7 @@ struct cals {
{&cals::op_rightshift, "RSHIFT"},
};
const char* arrow = line.contains("->");
- *w = line_view(arrow + 3, line.line + line.length);
+ *w = line_view(arrow + 3, line.line + line.length - 1);
for (auto op : ops) {
const char* p = line.contains(op.label);
@@ -137,8 +145,10 @@ struct cals {
line_view* y = new line_view();
line_view* w = new line_view();
auto f = parse(line, x, y, w);
- calls.insert({*w, f});
+ calls.insert({*w, {f, {result::c_unknown, 0}}});
}
};
+result day7(line_view, const char*);
+
} // namespace aoc2015
diff --git a/test/test_2015.cpp b/test/test_2015.cpp
index 159e36b..94f5cca 100644
--- a/test/test_2015.cpp
+++ b/test/test_2015.cpp
@@ -90,6 +90,7 @@ TEST_CASE("Probably a Fire Hazard", "[day6]") {
}
TEST_CASE("Some Assembly Required", "[day 7]") {
+ /*
aoc2015::cals cals;
cals.parse("1 -> ab");
cals.parse("8 RSHIFT ab -> x");
@@ -101,4 +102,9 @@ TEST_CASE("Some Assembly Required", "[day 7]") {
REQUIRE(16 == cals.compute("ac").value);
REQUIRE(17 == cals.compute("ae").value);
REQUIRE(65531 == cals.compute("f").value);
+ */
+
+ line_view lv = load_file("../src/2015/day7/input");
+ auto r = aoc2015::day7(lv, "a");
+ REQUIRE(3176 == r.value);
}