diff options
| author | Thomas Schmucker <ts@its1.de> | 2025-12-12 12:27:51 +0100 |
|---|---|---|
| committer | Thomas Schmucker <ts@its1.de> | 2025-12-12 12:27:51 +0100 |
| commit | 38a11596571d5281a9ba2c197d0e9cbebeb4039d (patch) | |
| tree | b1797dbfbdc806870771b73e68f5dccba5372c29 /2025 | |
| parent | b3dd0ea6decb1568570a2ebd8491fcd06919886e (diff) | |
| download | advent-of-code-38a11596571d5281a9ba2c197d0e9cbebeb4039d.tar.gz advent-of-code-38a11596571d5281a9ba2c197d0e9cbebeb4039d.tar.bz2 advent-of-code-38a11596571d5281a9ba2c197d0e9cbebeb4039d.zip | |
aoc 2025, day 9, alternative solution for part 2 using geos (shapely)
Diffstat (limited to '2025')
| -rw-r--r-- | 2025/src/day09-geos.cpp | 104 |
1 files changed, 104 insertions, 0 deletions
diff --git a/2025/src/day09-geos.cpp b/2025/src/day09-geos.cpp new file mode 100644 index 0000000..c7d7df4 --- /dev/null +++ b/2025/src/day09-geos.cpp | |||
| @@ -0,0 +1,104 @@ | |||
| 1 | #include <filesystem> | ||
| 2 | #include <fstream> | ||
| 3 | #include <iostream> | ||
| 4 | #include <tuple> | ||
| 5 | #include <vector> | ||
| 6 | |||
| 7 | // Geos | ||
| 8 | #include <geos/geom/CoordinateSequence.h> | ||
| 9 | #include <geos/geom/GeometryFactory.h> | ||
| 10 | #include <geos/geom/Polygon.h> | ||
| 11 | |||
| 12 | using namespace std; | ||
| 13 | using namespace geos; | ||
| 14 | using namespace geos::geom; | ||
| 15 | |||
| 16 | namespace { | ||
| 17 | |||
| 18 | using Pos = tuple<long, long>; // (x, y) | ||
| 19 | |||
| 20 | vector<Pos> | ||
| 21 | read_file(const filesystem::path& filename) | ||
| 22 | { | ||
| 23 | ifstream file{ filename }; | ||
| 24 | |||
| 25 | vector<Pos> data; | ||
| 26 | |||
| 27 | long x{}; | ||
| 28 | long y{}; | ||
| 29 | char skip{}; | ||
| 30 | |||
| 31 | while ( file >> x >> skip >> y ) { | ||
| 32 | data.emplace_back(x, y); | ||
| 33 | } | ||
| 34 | return data; | ||
| 35 | } | ||
| 36 | |||
| 37 | std::unique_ptr<Polygon> | ||
| 38 | makePolygon(const std::vector<Pos>& pts) | ||
| 39 | { | ||
| 40 | CoordinateSequence coords; | ||
| 41 | for ( const auto [x, y]: pts ) { | ||
| 42 | coords.add(static_cast<double>(x), static_cast<double>(y)); | ||
| 43 | } | ||
| 44 | |||
| 45 | // polygon schließen | ||
| 46 | coords.add(static_cast<double>(get<0>(pts[0])), static_cast<double>(get<1>(pts[0]))); | ||
| 47 | |||
| 48 | const auto* factory = GeometryFactory::getDefaultInstance(); | ||
| 49 | |||
| 50 | auto shell = factory->createLinearRing(coords); | ||
| 51 | |||
| 52 | return factory->createPolygon(std::move(shell), {}); | ||
| 53 | } | ||
| 54 | |||
| 55 | void | ||
| 56 | part2_geos(const vector<Pos>& data) | ||
| 57 | { | ||
| 58 | auto poly = makePolygon(data); | ||
| 59 | |||
| 60 | auto max_area = numeric_limits<long>::min(); | ||
| 61 | |||
| 62 | for ( size_t i = 0; i != data.size(); ++i ) { | ||
| 63 | for ( size_t j = i + 1; j != data.size(); ++j ) { | ||
| 64 | const auto [x1, y1] = data[i]; | ||
| 65 | const auto [x2, y2] = data[j]; | ||
| 66 | |||
| 67 | const auto width = abs(x1 - x2) + 1; | ||
| 68 | const auto height = abs(y1 - y2) + 1; | ||
| 69 | |||
| 70 | const auto area = width * height; | ||
| 71 | |||
| 72 | if ( area <= max_area ) { | ||
| 73 | continue; | ||
| 74 | } | ||
| 75 | |||
| 76 | const auto left = min(x1, x2); | ||
| 77 | const auto right = max(x1, x2); | ||
| 78 | const auto top = min(y1, y2); | ||
| 79 | const auto bottom = max(y1, y2); | ||
| 80 | |||
| 81 | auto rect = makePolygon(vector<Pos>{ | ||
| 82 | make_tuple(left, top), | ||
| 83 | make_tuple(right, top), | ||
| 84 | make_tuple(right, bottom), | ||
| 85 | make_tuple(left, bottom), | ||
| 86 | make_tuple(left, top), | ||
| 87 | }); | ||
| 88 | |||
| 89 | if ( poly->covers(rect.get()) ) { | ||
| 90 | max_area = area; | ||
| 91 | } | ||
| 92 | } | ||
| 93 | } | ||
| 94 | cout << "Part 2: " << max_area << '\n'; | ||
| 95 | } | ||
| 96 | |||
| 97 | } // namespace | ||
| 98 | |||
| 99 | int | ||
| 100 | main() | ||
| 101 | { | ||
| 102 | auto data = read_file("data/day09.txt"); | ||
| 103 | part2_geos(data); | ||
| 104 | } | ||
