diff --git a/res/2025/day09/test_input.txt b/res/2025/day09/test_input.txt new file mode 100644 index 0000000..c8563ea --- /dev/null +++ b/res/2025/day09/test_input.txt @@ -0,0 +1,8 @@ +7,1 +11,1 +11,7 +9,7 +9,5 +2,5 +2,3 +7,3 diff --git a/src/2021/Day04.cpp b/src/2021/Day04.cpp index 2d7818b..0bd7f3a 100644 --- a/src/2021/Day04.cpp +++ b/src/2021/Day04.cpp @@ -11,7 +11,7 @@ namespace y2021::day04 bool MarkAndCheck(Array2D& board, int number) { Index2D index = board.Find(number); - if (index) + if (index.IsValid()) { board[index] = -1; // Check board is filled diff --git a/src/2025/Day09.cpp b/src/2025/Day09.cpp index b2b7ef2..9457ad7 100644 --- a/src/2025/Day09.cpp +++ b/src/2025/Day09.cpp @@ -2,35 +2,174 @@ namespace y2025::day09 { - using InputType = std::vector; - REGISTER_DAY(2025, Day09, InputType, int); + using InputType = std::vector; + REGISTER_DAY(2025, Day09, InputType, int64_t); - REGISTER_TEST_EXAMPLE(2025, Day09, ExampleInput, 1, 0); - REGISTER_TEST(2025, Day09, Input, 1, 0); - REGISTER_TEST_EXAMPLE(2025, Day09, ExampleInput, 2, 0); - REGISTER_TEST(2025, Day09, Input, 2, 0); + REGISTER_TEST_EXAMPLE(2025, Day09, ExampleInput, 1, 50); + REGISTER_TEST(2025, Day09, Input, 1, 4773451098); + REGISTER_TEST_EXAMPLE(2025, Day09, ExampleInput, 2, 24); + REGISTER_TEST(2025, Day09, Input, 2, 1429075575); READ_INPUT(input) { - std::vector vec; + std::vector vec; std::string str; while (std::getline(input, str)) { std::stringstream ss{str}; - int n; - ss >> n; - vec.emplace_back(n); + Index2D index; + ss >> index.x >> "," >> index.y; + vec.emplace_back(index); } return vec; } + bool ValidArea(const Array2D& grid, Index2D from, Index2D to) + { + for (int y = from.y; y <= to.y; y++) + { + for (int x = from.x; x <= to.x; x++) + { + if (grid.Get(x, y) == 'O') + return false; + } + } + return true; + } + + Index2D GetMappedIndex(Index2D index, const std::map& xMap, const std::map& yMap) + { + index.x = xMap.at(index.x); + index.y = yMap.at(index.y); + return index; + } + + void ConvertToTopLeftAndBottomRight(Index2D& v1, Index2D& v2) + { + Index2D tl = Index2D{std::min(v1.x, v2.x), std::min(v1.y, v2.y)}; + Index2D br = Index2D{std::max(v1.x, v2.x), std::max(v1.y, v2.y)}; + v1 = tl; + v2 = br; + } + + void DrawEdges(Array2D& grid, + const std::vector& vertices, + const std::map& xMap, + const std::map& yMap) + { + for (int i = 0; i < vertices.size(); i++) + { + Index2D tl = GetMappedIndex(vertices[i], xMap, yMap); + Index2D br = GetMappedIndex(vertices[(i + 1) % vertices.size()], xMap, yMap); + ConvertToTopLeftAndBottomRight(tl, br); + + Index2D diff = Index2D{tl.y == br.y, tl.x == br.x}; + for (Index2D index = tl; index.x <= br.x && index.y <= br.y; index = index + diff) + { + grid[index] = 'x'; + } + } + } + + void FloodFill(Array2D& grid) + { + std::stack fill{{Index2D{0, 0}}}; + while (!fill.empty()) + { + Index2D top = fill.top(); + fill.pop(); + + std::vector neighbors = grid.GetNeighbors(top, false); + for (auto neighbor : neighbors) + { + if (grid.Get(neighbor) == '.') + { + grid[neighbor] = 'O'; + fill.emplace(neighbor); + } + } + } + } + + void CalculateMaps(std::vector vertices, std::map& xMap, std::map& yMap) + { + std::sort(vertices.begin(), vertices.end(), [](const Index2D& i1, const Index2D& i2) { return i1.x < i2.x; }); + xMap[vertices[0].x] = 1; + int count = 2; + for (int i = 1; i < vertices.size(); i++) + { + if (vertices[i - 1].x == vertices[i].x) + continue; + + xMap[vertices[i].x] = count; + count++; + } + + std::sort(vertices.begin(), vertices.end(), [](const Index2D& i1, const Index2D& i2) { return i1.y < i2.y; }); + yMap[vertices[0].y] = 1; + count = 2; + for (int i = 1; i < vertices.size(); i++) + { + if (vertices[i - 1].y == vertices[i].y) + continue; + + yMap[vertices[i].y] = count; + count++; + } + } + + int64_t CalculateArea(Index2D v1, Index2D v2) + { + Index2D diff = v2 - v1; + return (std::abs(static_cast(diff.x)) + 1) * (std::abs(static_cast(diff.y)) + 1); + } + OUTPUT1(input) { - return 0; + int64_t maxArea = 0; + for (int i = 0; i < input.size(); i++) + { + for (int j = i + 1; j < input.size(); j++) + { + maxArea = std::max(maxArea, CalculateArea(input[i], input[j])); + } + } + return maxArea; } OUTPUT2(input) { - return 0; + std::map xMap; + std::map yMap; + CalculateMaps(input, xMap, yMap); + + Array2D grid{static_cast(xMap.size()) + 2, static_cast(yMap.size()) + 2, '.'}; + + DrawEdges(grid, input, xMap, yMap); + FloodFill(grid); + + int64_t maxArea = 0; + for (int i = 0; i < input.size(); i++) + { + for (int j = i + 1; j < input.size(); j++) + { + Index2D tl = input[i]; + Index2D br = input[j]; + + ConvertToTopLeftAndBottomRight(tl, br); + int64_t area = CalculateArea(tl, br); + if (area > maxArea) + { + Index2D mapTl = GetMappedIndex(tl, xMap, yMap); + Index2D mapBr = GetMappedIndex(br, xMap, yMap); + if (ValidArea(grid, mapTl, mapBr)) + { + maxArea = area; + } + } + } + } + + return maxArea; } } diff --git a/src/common/lib/Array2D.h b/src/common/lib/Array2D.h index 635ece6..88c6ba9 100644 --- a/src/common/lib/Array2D.h +++ b/src/common/lib/Array2D.h @@ -14,11 +14,6 @@ struct Index2D return x != -1 && y != -1; } - operator bool() - { - return IsValid(); - } - Index2D operator+(const Index2D& other) const { return Index2D{x + other.x, y + other.y};