diff options
Diffstat (limited to 'src/2016/day23/aoc.cpp')
-rw-r--r-- | src/2016/day23/aoc.cpp | 117 |
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 |