aboutsummaryrefslogtreecommitdiff
path: root/src/2019/day10/aoc.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/2019/day10/aoc.h')
-rw-r--r--src/2019/day10/aoc.h97
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);
}