diff options
-rw-r--r-- | src/2021/day5/aoc.cpp | 15 | ||||
-rw-r--r-- | src/2021/day5/aoc.h | 33 | ||||
-rw-r--r-- | test/test_2021.cpp | 7 |
3 files changed, 50 insertions, 5 deletions
diff --git a/src/2021/day5/aoc.cpp b/src/2021/day5/aoc.cpp index 174882e..e9fc1ed 100644 --- a/src/2021/day5/aoc.cpp +++ b/src/2021/day5/aoc.cpp @@ -15,6 +15,16 @@ static void get_number(const char** pp, int* d) { } void fill(std::vector<int>& b1, std::vector<int>& b2, const line& l, int width) { + if (l.is_vertical() || l.is_horizontal()) { + l.traverse([&b1, &b2, width](line::point p) { + b1[p.y * width + p.x] += 1; + b2[p.y * width + p.x] += 1; + }); + } + + if (l.is_diagonal()) { + l.traverse([&b2, width](line::point p) { b2[p.y * width + p.x] += 1; }); + } } std::pair<int, int> day5(line_view file) { @@ -33,6 +43,9 @@ std::pair<int, int> day5(line_view file) { } p++; } + if (l.p2 < l.p1) { + std::swap(l.p1, l.p2); + } maxx = std::max(maxx, std::max(l.p1.x, l.p2.x)); maxy = std::max(maxy, std::max(l.p1.y, l.p2.y)); vs.push_back(l); @@ -42,7 +55,7 @@ std::pair<int, int> day5(line_view file) { maxx += 1; maxy += 1; - printf("%d, %d\n", maxx, maxy); + // printf("%d, %d\n", maxx, maxy); std::vector<int> board1(maxx * maxy, 0); std::vector<int> board2(maxx * maxy, 0); for (auto& l : vs) { 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); diff --git a/test/test_2021.cpp b/test/test_2021.cpp index 0096a8c..3208c4b 100644 --- a/test/test_2021.cpp +++ b/test/test_2021.cpp @@ -37,9 +37,8 @@ TEST_CASE("Giant Squid", "[2021]") { } TEST_CASE("Hydrothermal Venture", "[2021]") { - line_view lv = load_file("../src/2021/day5/input0"); + line_view lv = load_file("../src/2021/day5/input"); auto p = aoc2021::day5(lv); - // REQUIRE(5774 == p.first); - REQUIRE(5 == p.first); - REQUIRE(12 == p.second); + REQUIRE(5774 == p.first); + REQUIRE(18423 == p.second); } |