aboutsummaryrefslogtreecommitdiff
path: root/src/2016/day23/aoc.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/2016/day23/aoc.cpp')
-rw-r--r--src/2016/day23/aoc.cpp117
1 files changed, 116 insertions, 1 deletions
diff --git a/src/2016/day23/aoc.cpp b/src/2016/day23/aoc.cpp
index 56304eb..9b6a6ba 100644
--- a/src/2016/day23/aoc.cpp
+++ b/src/2016/day23/aoc.cpp
@@ -2,5 +2,120 @@
namespace aoc2016 {
-std::pair<int64_t, int64_t> day23(line_view) { return {0, 0}; }
+static int registers[4] = {7, 0, 0, 0};
+
+static int& get(int i) { return registers[i]; }
+// c = a,b,c,d
+static int& get(char c) { return get(c - 'a'); }
+
+struct instruction23 {
+ mutable size_t toggles = 0;
+ line_view todo;
+
+ instruction23(line_view l) : todo(l) {}
+
+ int which() {
+ std::cout << todo << std::endl;
+ const char* p = todo.line;
+ switch (*p) {
+ case 'c':
+ return 0;
+ case 'i':
+ return 1;
+ case 'd':
+ return 2;
+ case 'j':
+ return 3;
+ case 't':
+ return 4;
+ default:
+ break;
+ }
+ return 4;
+ }
+};
+
+static void get_number(const char** pp, int* d) {
+ const char* p = *pp;
+ int sign = 1;
+ if (*p == '-') {
+ sign = -1;
+ p += 1;
+ }
+ while (*p >= '0' && *p <= '9') {
+ *d = *d * 10 + *p - '0';
+ p++;
+ }
+ *d *= sign;
+ *pp = p;
+}
+
+typedef void (*todo_f)(size_t*, const char*, const std::vector<instruction23>&);
+static void cpy(size_t* i, const char* p, const std::vector<instruction23>& todos) {
+ int d{0};
+ if (*p >= '0' && *p <= '9') {
+ get_number(&p, &d);
+ p += 1;
+ } else {
+ d = get(*p);
+ p += 2;
+ }
+ get(*p) = d;
+ *i += 1;
+}
+
+static void inc(size_t* i, const char* p, const std::vector<instruction23>& todos) {
+ get(*p) += 1;
+ *i += 1;
+}
+
+static void dec(size_t* i, const char* p, const std::vector<instruction23>& todos) {
+ get(*p) -= 1;
+ *i += 1;
+}
+
+static void jnz(size_t* i, const char* p, const std::vector<instruction23>& todos) {
+ bool condition = *p >= '0' && *p <= '9' ? *p - '0' : get(*p) != 0;
+ if (condition) {
+ p += 2;
+ int offset{0};
+ get_number(&p, &offset);
+ *i += offset;
+ } else {
+ *i += 1;
+ }
+}
+
+static void tgl(size_t* i, const char* p, const std::vector<instruction23>& todos) {
+ size_t next = *i + get(*p);
+ if (next < todos.size()) {
+ todos[next].toggles += 1;
+ }
+ *i += 1;
+}
+
+static void non(size_t* i, const char* p, const std::vector<instruction23>&) { *i += 1; }
+
+static size_t exec(size_t i, const std::vector<instruction23>& todos) {
+ if (i < todos.size()) {
+ todo_f fs[6] = {cpy, inc, dec, jnz, tgl, non};
+ auto d = todos[i];
+ fs[d.which()](&i, d.todo.line + 4, todos);
+ }
+ return i;
+}
+
+std::pair<int64_t, int64_t> day23(line_view file) {
+ std::vector<instruction23> todos;
+ per_line(file, [&todos](line_view lv) {
+ todos.emplace_back(line_view{lv.line, lv.length - 1});
+ return true;
+ });
+ size_t i = 0;
+ while (i < todos.size()) {
+ i = exec(i, todos);
+ }
+
+ return {0, 0};
+}
} // namespace aoc2016