diff options
Diffstat (limited to 'src/2021/day5/aoc.h')
-rw-r--r-- | src/2021/day5/aoc.h | 33 |
1 files changed, 33 insertions, 0 deletions
diff --git a/src/2021/day5/aoc.h b/src/2021/day5/aoc.h index c57f439..bd8c346 100644 --- a/src/2021/day5/aoc.h +++ b/src/2021/day5/aoc.h @@ -1,6 +1,7 @@ #pragma once #include "common.h" +#include <math.h> namespace aoc2021 { @@ -8,9 +9,41 @@ struct line { struct point { int x; int y; + + bool operator<(const point& p) const noexcept { return x < p.x ? true : x > p.x ? false : y < p.y; } + point move_h(int d) { return {x + d, y}; } + point move_v(int d) { return {x, y + d}; } + point move_p(int d) { return {x + d, y + d}; } + point move_d(int d) { return {x + d, y - d}; } }; point p1; point p2; + + bool is_vertical() const noexcept { return p1.x == p2.x; } + bool is_horizontal() const noexcept { return p1.y == p2.y; } + bool is_diagonal() const noexcept { return std::abs(p2.x - p1.x) == std::abs(p2.y - p1.y); } + + template <typename F> + void traverse(F&& f) const noexcept { + auto next = [this](point x) { + if (is_vertical()) { + return x.move_v(1); + } + if (is_horizontal()) { + return x.move_h(1); + } + if (is_diagonal()) { + return p2.y > p1.y ? x.move_p(1) : x.move_d(1); + } + return x; + }; + point p = p1; + while (p < p2) { + f(p); + p = next(p); + } + f(p); // p == p2 + } }; std::pair<int, int> day5(line_view); |