#include "aoc.h" #include namespace aoc2016 { static std::map bots = {}; static std::map outputs = {}; static bot* get(int i, std::map& bs) { auto p = bs.insert({i, nullptr}); if (p.second) { bot* b = new bot; b->idx = i; p.first->second = b; } return p.first->second; } typedef bot* (*get_method)(int); bot* get_bot(int i) { return get(i, bots); } bot* get_output(int i) { return get(i, outputs); } static void get_number(const char** pp, int* d) { const char* p = *pp; while (*p >= '0' && *p <= '9') { *d = *d * 10 + *p - '0'; p++; } *pp = p; } void parse_three(const char* p) { int is[3] = {0, 0, 0}; int i{0}; get_method gets[2] = {get_bot, get_bot}; while (true) { if (*p >= '0' && *p <= '9') { if (i == 1 || i == 2) { if (*(p - 3) == 'u') { gets[i - 1] = get_output; } // if (*(p - 3) == 'o') { // gets[i - 1] = get_bot; // } } get_number(&p, is + i); i++; } if (*p == '\n') break; p++; } bot* b0 = get_bot(is[0]); bot* b1 = gets[0](is[1]); b1->is_output = gets[0] == get_output; bot* b2 = gets[1](is[2]); b2->is_output = gets[1] == get_output; b0->outputs[0] = b1; b0->outputs[1] = b2; // const char* ds[2] = {"bot", "output"}; // printf("%d %d[%s] %d[%s]\n", b0->idx, b1->idx, ds[(int)b1->is_output], b2->idx, ds[(int)b2->is_output]); } void parse_two(const char* p) { int is[2] = {0, 0}; int i{0}; while (true) { if (*p >= '0' && *p <= '9') { get_number(&p, is + i); i++; } if (*p == '\n') break; p++; } get_bot(is[1])->set(is[0]); } void give(bot* b0, bot* b1, int v, int i) { if (b1 != nullptr) { // const char* ds[2] = {"bot", "output"}; // printf("%d give %d[%s] value %d\n", b0->idx, b1->idx, ds[(int)b1->is_output], v); if (b1->is_output) { b1->get(v); } else { b1->set(v); } b0->vs[i] = 0; } } int64_t robot_work(int l, int h, int* idx) { while (true) { size_t n{0}; for (auto& kv : bots) { bot* b = kv.second; if (b->can_give()) { n += 1; int l0 = b->vs[0]; int h0 = b->vs[1]; if (l0 == l && h0 == h) { *idx = b->idx; } give(b, b->outputs[0], l0, 0); give(b, b->outputs[1], h0, 1); } } if (n == 0) break; } int64_t v{1}; for (int i = 0; i < 3; i++) { v *= get_output(i)->values[0]; } return v; } void print(int x, bot* b) { printf("\noutput %d\n", x); for (auto i : b->values) { printf("%d ", i); } } std::pair day10(line_view file) { per_line(file, [](line_view lv) { const char* p = lv.line; if (*p == 'b') { parse_three(p); } if (*p == 'v') { parse_two(p); } return true; }); int idx{INT32_MAX}; auto o = robot_work(17, 61, &idx); return {idx, o}; } } // namespace aoc2016