#include "aoc.h" namespace aoc2016 { static int registers[4] = {7, 0, 0, 0}; static size_t clock_signal = 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; bool toggle_is_odd = toggles & 1; switch (*p) { case 'c': return toggle_is_odd ? 3 : 0; case 'i': return toggle_is_odd ? 2 : 1; case 'd': return toggle_is_odd ? 1 : 2; case 'j': return toggle_is_odd ? 0 : 3; case 't': return toggle_is_odd ? 1 : 4; case 'o': return toggle_is_odd ? 1 : 5; default: break; } return 6; } }; 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&); static void cpy(size_t* i, const char* p, const std::vector& todos) { int d{0}; if (*p >= 'a' && *p <= 'd') { d = get(*p); p += 2; } else { get_number(&p, &d); p += 1; } if (*p >= 'a' && *p <= 'd') { get(*p) = d; } *i += 1; } static void inc(size_t* i, const char* p, const std::vector& todos) { get(*p) += 1; *i += 1; } static void dec(size_t* i, const char* p, const std::vector& todos) { get(*p) -= 1; *i += 1; } static void out(size_t* i, const char* p, const std::vector& todos) { if (get(*p) == static_cast(clock_signal & 1)) { *i += 1; clock_signal += 1; } else { printf("%zu\n", clock_signal); // printf("%d %d %d %d\n", get('a'), get('b'), get('c'), get('d')); *i = UINT64_MAX; } } static void jnz(size_t* i, const char* p, const std::vector& todos) { int d{0}; bool condition = false; bool is_number = false; if (*p >= '0' && *p <= '9') { is_number = true; get_number(&p, &d); condition = d != 0; } else { condition = get(*p) != 0; } if (condition) { p += is_number ? 1 : 2; int offset{0}; if (*p >= 'a' && *p <= 'd') { offset = get(*p); } else { get_number(&p, &offset); } *i += offset; } else { *i += 1; } } static void tgl(size_t* i, const char* p, const std::vector& 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&) { *i += 1; } static size_t exec(size_t i, const std::vector& todos) { todo_f fs[7] = {cpy, inc, dec, jnz, tgl, out, non}; // const char *ds[6] = {"cpy", "inc", "dec", "jnz", "tgl", "non"}; auto d = todos[i]; auto x = d.which(); // char param[30] = {0}; // memcpy(param, d.todo.line + 4, d.todo.length - 4); // printf("%s %s\n", ds[x], param); fs[x](&i, d.todo.line + 4, todos); // printf("%d %d %d %d\n", get('a'), get('b'), get('c'), get('d')); return i; } std::pair day23(line_view file) { std::vector 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 {get('a'), 0}; } std::pair day25(line_view file) { for (int i = 0; i < 10000; i++) { printf("%d ", i); get('a') = i; get('b') = 0; get('c') = 0; get('d') = 0; clock_signal = 0; day23(file); } return {0, 0}; } } // namespace aoc2016