aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorkaiwu <kaiwu2004@gmail.com>2023-03-15 10:42:56 +0800
committerkaiwu <kaiwu2004@gmail.com>2023-03-15 10:42:56 +0800
commit010adeb053704218fda2ffb991d0d166c6d632d0 (patch)
tree5c918841444998f1fc6dd4fe6d8b0017673ad6d4
parentc2f5d41ff9b21d7a4aac0bfb7c34bbb57a38c82b (diff)
downloadadvent-of-code-010adeb053704218fda2ffb991d0d166c6d632d0.tar.gz
advent-of-code-010adeb053704218fda2ffb991d0d166c6d632d0.zip
2017 day23 part1
-rw-r--r--src/2017/day23/README.md11
-rw-r--r--src/2017/day23/aoc.cpp101
-rw-r--r--test/test_2017.cpp2
3 files changed, 112 insertions, 2 deletions
diff --git a/src/2017/day23/README.md b/src/2017/day23/README.md
index 34f9caf..0afb1af 100644
--- a/src/2017/day23/README.md
+++ b/src/2017/day23/README.md
@@ -13,3 +13,14 @@ The coprocessor is currently set to some kind of debug mode, which allows for te
If you run the program (your puzzle input), how many times is the mul instruction invoked?
+--- Part Two ---
+Now, it's time to fix the problem.
+
+The debug mode switch is wired directly to register a. You flip the switch, which makes register a now start at 1 when the program is executed.
+
+Immediately, the coprocessor begins to overheat. Whoever wrote this program obviously didn't choose a very efficient implementation. You'll need to optimize the program if it has any hope of completing before Santa needs that printer working.
+
+The coprocessor's ultimate goal is to determine the final value left in register h once the program completes. Technically, if it had that... it wouldn't even need to run the program.
+
+After setting register a to 1, if the program were to run to completion, what value would be left in register h?
+
diff --git a/src/2017/day23/aoc.cpp b/src/2017/day23/aoc.cpp
index 444cec9..7d990e3 100644
--- a/src/2017/day23/aoc.cpp
+++ b/src/2017/day23/aoc.cpp
@@ -2,5 +2,104 @@
namespace aoc2017 {
-std::pair<int64_t, int64_t> day23(line_view) { return {0, 0}; }
+static int64_t& get(char x, int64_t rs[26]) { return rs[x - 'a']; }
+static void get_number(const char** pp, int64_t* d) {
+ const char* p = *pp;
+ int sign = 1;
+ if (*p == '-') {
+ sign = -1;
+ p++;
+ }
+ while (*p >= '0' && *p <= '9') {
+ *d = *d * 10 + *p - '0';
+ p++;
+ }
+ *d *= sign;
+ *pp = p;
+}
+
+static int64_t get_number(const char* p, int64_t rs[26]) {
+ int64_t d{0};
+ if (*p == '-' || (*p >= '0' && (*p <= '9'))) {
+ get_number(&p, &d);
+ } else {
+ d = get(*p, rs);
+ }
+ return d;
+}
+
+typedef void (*f23)(size_t* i, const char* p1, const char* p2, int64_t rs[26]);
+
+static void set(size_t* i, const char* p1, const char* p2, int64_t rs[26]) {
+ get(*p1, rs) = get_number(p2, rs);
+ *i += 1;
+}
+
+static void sub(size_t* i, const char* p1, const char* p2, int64_t rs[26]) {
+ get(*p1, rs) -= get_number(p2, rs);
+ *i += 1;
+}
+
+static void mul(size_t* i, const char* p1, const char* p2, int64_t rs[26]) {
+ get(*p1, rs) *= get_number(p2, rs);
+ *i += 1;
+}
+
+static void jnz(size_t* i, const char* p1, const char* p2, int64_t rs[26]) {
+ auto d1 = get_number(p1, rs);
+ auto d2 = get_number(p2, rs);
+ *i += d1 != 0 ? d2 : 1;
+}
+
+static struct {
+ f23 f;
+ const char* s;
+ int c;
+} fs[4] = {{set, "set", 0}, {sub, "sub", 0}, {mul, "mul", 0}, {jnz, "jnz", 0}};
+
+static size_t exec(size_t index, const std::vector<line_view>& todos, int64_t rs[26]) {
+ if (index < todos.size()) {
+ auto& todo = todos[index];
+ const char* p = todo.line;
+ auto match = [](const char* p, const char* p0) -> bool {
+ for (int i = 0; i < 3; i++) {
+ if (*(p + i) != *(p0 + i)) {
+ return false;
+ }
+ }
+ return true;
+ };
+
+ for (auto& fx : fs) {
+ if (match(p, fx.s)) {
+ fx.c += 1;
+ fx.f(&index, p + 4, p + 6, rs);
+ break;
+ }
+ }
+ }
+ return index;
+}
+
+static void part1(const std::vector<line_view>& todos) {
+ size_t index{0};
+ int64_t rs[26] = {0};
+
+ while (index < todos.size()) {
+ index = exec(index, todos, rs);
+ }
+}
+
+std::pair<int64_t, int64_t> day23(line_view file) {
+ std::vector<line_view> todos;
+ per_line(file, [&todos](line_view lv) {
+ todos.push_back(lv);
+ return true;
+ });
+
+ part1(todos);
+ int64_t t0 = fs[2].c;
+
+ return {t0, 0};
+}
} // namespace aoc2017
diff --git a/test/test_2017.cpp b/test/test_2017.cpp
index 4e25464..a7382f4 100644
--- a/test/test_2017.cpp
+++ b/test/test_2017.cpp
@@ -221,7 +221,7 @@ TEST_CASE("Sporifica Virus", "[2017]") {
TEST_CASE("Coprocessor Conflagration", "[2017]") {
line_view lv = load_file("../src/2017/day23/input");
auto p = aoc2017::day23(lv);
- REQUIRE(0 == p.first);
+ REQUIRE(4225 == p.first);
REQUIRE(0 == p.second);
}