diff options
Diffstat (limited to 'src/2017/day22/aoc.cpp')
-rw-r--r-- | src/2017/day22/aoc.cpp | 90 |
1 files changed, 89 insertions, 1 deletions
diff --git a/src/2017/day22/aoc.cpp b/src/2017/day22/aoc.cpp index b2e2dfb..3e9a907 100644 --- a/src/2017/day22/aoc.cpp +++ b/src/2017/day22/aoc.cpp @@ -1,6 +1,94 @@ #include "aoc.h" +#include <set> namespace aoc2017 { -std::pair<int64_t, int64_t> day22(line_view) { return {0, 0}; } +static int radias = 12; // demo 25/2 = 12 input +enum facing { + f_up, + f_down, + f_right, + f_left, +}; + +struct vpos { + int x; + int y; + facing f; +}; + +static vpos turn_right(vpos p) { + facing fs[4] = {f_right, f_left, f_down, f_up}; + return {p.x, p.y, fs[(int)p.f]}; +} + +static vpos turn_left(vpos p) { + facing fs[4] = {f_left, f_right, f_up, f_down}; + return {p.x, p.y, fs[(int)p.f]}; +} + +static vpos move(vpos p) { + vpos vs[4] = { + {p.x, p.y - 1, p.f}, + {p.x, p.y + 1, p.f}, + {p.x + 1, p.y, p.f}, + {p.x - 1, p.y, p.f}, + }; + return vs[(int)p.f]; +} + +vpos burst(std::set<node22>& infected, vpos p, int* c) { + auto it = infected.find({p.x, p.y}); + bool is_infected = it != infected.end(); + // If the current node is infected, it turns to its right. Otherwise, it turns to its left. (Turning is done in-place; + // the current node does not change.) + vpos px = is_infected ? turn_right(p) : turn_left(p); + + // If the current node is clean, it becomes infected. Otherwise, it becomes + // cleaned. (This is done after the node is considered for the purposes of changing direction.) The virus carrier + if (!is_infected) { + infected.insert({p.x, p.y}); + *c += 1; + } else { + infected.erase(it); + } + + // moves forward one node in the direction it is facing. + px = move(px); + return px; +} + +static void load(std::set<node22>& is, int r, line_view lv) { + const char* p = lv.line; + int x = 0; + while (*(p + x) != '\n') { + if (*(p + x) == '#') { + node22 n{x - radias, r - radias}; + is.insert(n); + } + x++; + } +} + +std::pair<int64_t, int64_t> day22(line_view file) { + std::set<node22> infected; + + int r{0}; + per_line(file, [&r, &infected](line_view lv) { + load(infected, r++, lv); + return true; + }); + + vpos p{0, 0, f_up}; + int t0{0}; + for (int i = 0; i < 10000; i++) { + p = burst(infected, p, &t0); + } + + // for (auto& n : infected) { + // printf("%d,%d\n", n.x, n.y); + // } + return {t0, 0}; +} + } // namespace aoc2017 |