aboutsummaryrefslogtreecommitdiff
path: root/src/2017/day18/aoc.cpp
diff options
context:
space:
mode:
authorkaiwu <kaiwu2004@gmail.com>2023-02-10 16:55:27 +0800
committerkaiwu <kaiwu2004@gmail.com>2023-02-10 16:55:27 +0800
commit43449739d8209d7d2b0df55722e3f5143640fd3b (patch)
tree578217deafb1a84cda58a22ae10697515c8c8a93 /src/2017/day18/aoc.cpp
parent46169a9af36bf31514ed3a12f11b2a9ca81ad84a (diff)
downloadadvent-of-code-43449739d8209d7d2b0df55722e3f5143640fd3b.tar.gz
advent-of-code-43449739d8209d7d2b0df55722e3f5143640fd3b.zip
2017 day18
Diffstat (limited to 'src/2017/day18/aoc.cpp')
-rw-r--r--src/2017/day18/aoc.cpp154
1 files changed, 153 insertions, 1 deletions
diff --git a/src/2017/day18/aoc.cpp b/src/2017/day18/aoc.cpp
index 1308c9e..9cef4c9 100644
--- a/src/2017/day18/aoc.cpp
+++ b/src/2017/day18/aoc.cpp
@@ -1,6 +1,158 @@
#include "aoc.h"
+#include <deque>
namespace aoc2017 {
+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;
+}
-std::pair<int64_t, int64_t> day18(line_view) { return {0, 0}; }
+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 (*f18)(size_t*, const char*, const char*, int64_t rs[26], std::deque<int64_t>* qs[2]);
+
+static void snd(size_t* i, const char* p1, const char* p2, int64_t rs[26], std::deque<int64_t>* qs[2]) {
+ qs[0]->push_back(get(*p1, rs));
+ *i += 1;
+}
+
+static void rcv0(size_t* i, const char* p1, const char* p2, int64_t rs[26], std::deque<int64_t>* qs[2]) {
+ auto d = get_number(p1, rs);
+ if (d != 0) {
+ // printf("%ld\n", sounds.back());
+ *i = INT64_MAX - 1;
+ }
+ *i += 1;
+}
+
+static void rcv1(size_t* i, const char* p1, const char* p2, int64_t rs[26], std::deque<int64_t>* qs[2]) {
+ if (!qs[1]->empty()) {
+ auto x = qs[1]->front();
+ qs[1]->pop_front();
+ get(*p1, rs) = x;
+ *i += 1;
+ }
+}
+
+static void set(size_t* i, const char* p1, const char* p2, int64_t rs[26], std::deque<int64_t>* qs[2]) {
+ get(*p1, rs) = get_number(p2, rs);
+ *i += 1;
+}
+
+static void add(size_t* i, const char* p1, const char* p2, int64_t rs[26], std::deque<int64_t>* qs[2]) {
+ 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], std::deque<int64_t>* qs[2]) {
+ get(*p1, rs) *= get_number(p2, rs);
+ *i += 1;
+}
+
+static void mod(size_t* i, const char* p1, const char* p2, int64_t rs[26], std::deque<int64_t>* qs[2]) {
+ get(*p1, rs) %= get_number(p2, rs);
+ *i += 1;
+}
+
+static void jgz(size_t* i, const char* p1, const char* p2, int64_t rs[26], std::deque<int64_t>* qs[2]) {
+ auto d0 = get_number(p1, rs);
+ auto d1 = get_number(p2, rs);
+ *i += d0 > 0 ? d1 : 1;
+}
+
+// static void print() {
+// char as[] = {'i', 'a', 'p', 'f', 'b'};
+// for (auto& a: as) {
+// printf("[%c: %ld] ", a, get(a));
+// }
+// printf("\n");
+// }
+
+static size_t exec(size_t index, const std::vector<line_view>& todos, int64_t rs[26], std::deque<int64_t>* qs[2],
+ f18 rcv) {
+ if (index < todos.size()) {
+ f18 fs[] = {snd, set, add, mul, mod, jgz, rcv};
+ const char* cs[] = {"snd", "set", "add", "mul", "mod", "jgz", "rcv"};
+ 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 (size_t i = 0; i < 7; i++) {
+ if (match(p, cs[i])) {
+ fs[i](&index, p + 4, p + 6, rs, qs);
+ break;
+ }
+ }
+ }
+ return index;
+}
+
+static int64_t part1(const std::vector<line_view>& todos) {
+ size_t index{0};
+ int64_t rs[26] = {0};
+ std::deque<int64_t> q;
+ std::deque<int64_t>* qs[2] = {&q, &q};
+
+ while (index < todos.size()) {
+ index = exec(index, todos, rs, qs, rcv0);
+ }
+ return q.back();
+}
+
+static void part2(const std::vector<line_view>& todos) {
+ size_t i0{0};
+ size_t i1{0};
+
+ int64_t rs0[26] = {0};
+ get('p', rs0) = 0;
+ int64_t rs1[26] = {0};
+ get('p', rs1) = 1;
+
+ std::deque<int64_t> q0;
+ std::deque<int64_t> q1;
+ std::deque<int64_t>* qs0[2] = {&q1, &q0};
+ std::deque<int64_t>* qs1[2] = {&q0, &q1};
+
+ while (i0 < todos.size() && i1 < todos.size()) {
+ i0 = exec(i0, todos, rs0, qs0, rcv1);
+ i1 = exec(i1, todos, rs1, qs1, rcv1);
+ }
+}
+
+std::pair<int64_t, int64_t> day18(line_view file) {
+ std::vector<line_view> todos;
+ per_line(file, [&todos](line_view lv) {
+ todos.push_back(lv);
+ return true;
+ });
+
+ auto t0 = part1(todos);
+ return {t0, 0};
+}
} // namespace aoc2017