diff options
Diffstat (limited to 'src/2019/day10/aoc.h')
-rw-r--r-- | src/2019/day10/aoc.h | 97 |
1 files changed, 97 insertions, 0 deletions
diff --git a/src/2019/day10/aoc.h b/src/2019/day10/aoc.h index 9951322..d3cdb76 100644 --- a/src/2019/day10/aoc.h +++ b/src/2019/day10/aoc.h @@ -1,7 +1,104 @@ #pragma once #include "common.h" +#include <math.h> namespace aoc2019 { +struct belt { + static constexpr int grid = 34; + + struct distance { + int dx; + int dy; + }; + + struct pos { + int x; + int y; + + friend bool operator==(const pos &p1, const pos &p2) { + return p1.x == p2.x && p1.y == p2.y; + } + }; + + char map[grid * grid] = {0}; + + belt(const belt& b) { + memcpy(map, b.map, grid * grid); + } + + belt() {} + + char& get(int x, int y) { + return map[y * grid + x]; + } + + char& get(pos p) { + return get(p.x, p.y); + } + + void load(line_view lv, int row) { + const char* p = lv.line; + for (int i = 0; i < grid; i++) { + get(i, row) = *(p + i); + } + } + + distance diff(pos px, pos p) const noexcept { + auto d = distance{px.x - p.x, px.y - p.y}; + int g = gcd(std::abs(d.dx), std::abs(d.dy)); + return distance {d.dx / g, d.dy / g}; + } + + bool valid (pos p) const noexcept { + return p.x >= 0 && p.x < grid && p.y >= 0 && p.y < grid; + } + + pos next(pos p, distance d) const noexcept { + return pos{p.x + d.dx, p.y + d.dy}; + } + + bool blocked(pos p, pos m) { + auto d = diff(p, m); + auto n = next(m, d); + while (valid(n) && !(n == p)) { + if (get(n) == '#') { + return true; + } + n = next(n, d); + } + return false; + } + + template<typename F, typename... Args> + void iterate(F&& f, Args&&... args) { + for(int y = 0; y < grid; y++) { + for (int x = 0; x < grid; x++) { + f(pos{x, y}, std::forward(args)...); + } + } + } + + void print() { + iterate([this](pos p){ + printf("%c", get(p)); + if (p.x == grid - 1) { + printf("\n"); + } + }); + printf("\n"); + } + + void count(pos m, int* c) { + iterate([this, &m, &c](pos p){ + if (get(p) == '#' && !(p == m)) { + if (!blocked(p, m)) { + *c += 1; + } + } + }); + } +}; + std::pair<int, int> day10(line_view); } |