aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/2021/day5/aoc.cpp15
-rw-r--r--src/2021/day5/aoc.h33
-rw-r--r--test/test_2021.cpp7
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);
}