diff options
| author | Thomas Schmucker <ts@its1.de> | 2025-12-08 23:58:23 +0100 |
|---|---|---|
| committer | Thomas Schmucker <ts@its1.de> | 2025-12-08 23:58:23 +0100 |
| commit | 5f41cc49734c7d1ef304be37b60e19349b314193 (patch) | |
| tree | 912a5c9b1dc8176b24bc3a194e09f145bfd83100 /2025/src/day08.cpp | |
| parent | 2e9d0706ec4cdfa7171dd079d497cd81ee03bd36 (diff) | |
| download | advent-of-code-5f41cc49734c7d1ef304be37b60e19349b314193.tar.gz advent-of-code-5f41cc49734c7d1ef304be37b60e19349b314193.tar.bz2 advent-of-code-5f41cc49734c7d1ef304be37b60e19349b314193.zip | |
aoc 2025, day 8, cleanup
Diffstat (limited to '2025/src/day08.cpp')
| -rw-r--r-- | 2025/src/day08.cpp | 83 |
1 files changed, 46 insertions, 37 deletions
diff --git a/2025/src/day08.cpp b/2025/src/day08.cpp index 7a3c3b1..6fa3cd6 100644 --- a/2025/src/day08.cpp +++ b/2025/src/day08.cpp | |||
| @@ -2,7 +2,6 @@ | |||
| 2 | #include <filesystem> | 2 | #include <filesystem> |
| 3 | #include <fstream> | 3 | #include <fstream> |
| 4 | #include <iostream> | 4 | #include <iostream> |
| 5 | #include <map> | ||
| 6 | #include <tuple> | 5 | #include <tuple> |
| 7 | #include <vector> | 6 | #include <vector> |
| 8 | 7 | ||
| @@ -14,6 +13,7 @@ class UnionFind { | |||
| 14 | public: | 13 | public: |
| 15 | explicit UnionFind(size_t size) | 14 | explicit UnionFind(size_t size) |
| 16 | : parent_(size) | 15 | : parent_(size) |
| 16 | , size_(size, 1) | ||
| 17 | { | 17 | { |
| 18 | for ( size_t i = 0; i != size; ++i ) { | 18 | for ( size_t i = 0; i != size; ++i ) { |
| 19 | parent_[i] = i; | 19 | parent_[i] = i; |
| @@ -33,18 +33,39 @@ public: | |||
| 33 | a = find(a); | 33 | a = find(a); |
| 34 | b = find(b); | 34 | b = find(b); |
| 35 | 35 | ||
| 36 | if ( a != b ) { | 36 | if ( a == b ) { |
| 37 | parent_[b] = a; | 37 | return false; |
| 38 | return true; | ||
| 39 | } | 38 | } |
| 40 | return false; | 39 | |
| 40 | if ( size_[a] < size_[b] ) { | ||
| 41 | swap(a, b); | ||
| 42 | } | ||
| 43 | |||
| 44 | parent_[b] = a; | ||
| 45 | size_[a] += size_[b]; | ||
| 46 | |||
| 47 | return true; | ||
| 48 | } | ||
| 49 | |||
| 50 | [[nodiscard]] | ||
| 51 | vector<size_t> get_component_sizes() const | ||
| 52 | { | ||
| 53 | vector<size_t> sizes; | ||
| 54 | for ( size_t i = 0; i != parent_.size(); ++i ) { | ||
| 55 | if ( parent_[i] == i ) { | ||
| 56 | sizes.emplace_back(size_[i]); | ||
| 57 | } | ||
| 58 | } | ||
| 59 | return sizes; | ||
| 41 | } | 60 | } |
| 42 | 61 | ||
| 43 | private: | 62 | private: |
| 44 | vector<size_t> parent_; | 63 | vector<size_t> parent_; |
| 64 | vector<size_t> size_; | ||
| 45 | }; | 65 | }; |
| 46 | 66 | ||
| 47 | using Pos = tuple<long, long, long>; | 67 | using Pos = tuple<long, long, long>; // (x, y, z) |
| 68 | using Dist = tuple<double, size_t, size_t>; // (Distanz, Von, Nach) | ||
| 48 | 69 | ||
| 49 | vector<Pos> | 70 | vector<Pos> |
| 50 | read_file(const filesystem::path& filename) | 71 | read_file(const filesystem::path& filename) |
| @@ -74,11 +95,9 @@ get_distance(const Pos& pos1, const Pos& pos2) | |||
| 74 | return hypot(x1 - x2, y1 - y2, z1 - z2); | 95 | return hypot(x1 - x2, y1 - y2, z1 - z2); |
| 75 | } | 96 | } |
| 76 | 97 | ||
| 77 | void | 98 | vector<Dist> |
| 78 | part1(const vector<Pos>& list) | 99 | get_distances(const vector<Pos>& list) |
| 79 | { | 100 | { |
| 80 | using Dist = tuple<double, size_t, size_t>; // (Distanz, Von, Nach) | ||
| 81 | |||
| 82 | // Distanzen paarweise erfassen... | 101 | // Distanzen paarweise erfassen... |
| 83 | vector<Dist> dists; | 102 | vector<Dist> dists; |
| 84 | for ( size_t i = 0; i != list.size(); ++i ) { | 103 | for ( size_t i = 0; i != list.size(); ++i ) { |
| @@ -90,28 +109,26 @@ part1(const vector<Pos>& list) | |||
| 90 | // ... und nach Distanz sortieren | 109 | // ... und nach Distanz sortieren |
| 91 | ranges::sort(dists); | 110 | ranges::sort(dists); |
| 92 | 111 | ||
| 112 | return dists; | ||
| 113 | } | ||
| 114 | |||
| 115 | void | ||
| 116 | part1(const vector<Pos>& list) | ||
| 117 | { | ||
| 118 | const auto dists = get_distances(list); | ||
| 119 | |||
| 93 | UnionFind unionFind(list.size()); | 120 | UnionFind unionFind(list.size()); |
| 94 | 121 | ||
| 95 | // die kĂŒrzesten 1000 Elemente verbinden | 122 | // die nĂ€chsten 1000 Paare verbinden |
| 96 | for ( size_t i = 0; i != 1000; ++i ) { | 123 | for ( size_t i = 0; i != 1000; ++i ) { |
| 97 | const auto [dist, a, b] = dists[i]; | 124 | const auto [dist, a, b] = dists[i]; |
| 98 | unionFind.unite(a, b); | 125 | unionFind.unite(a, b); |
| 99 | } | 126 | } |
| 100 | 127 | ||
| 101 | // die LÀngen der Verbindungen zÀhlen | 128 | auto sizes = unionFind.get_component_sizes(); |
| 102 | map<size_t, size_t> compSizes; | ||
| 103 | for ( size_t i = 0; i != list.size(); ++i ) { | ||
| 104 | compSizes[unionFind.find(i)]++; | ||
| 105 | } | ||
| 106 | |||
| 107 | // GröĂen finden | ||
| 108 | vector<size_t> sizes; | ||
| 109 | for ( const auto& [root, size]: compSizes ) { | ||
| 110 | sizes.emplace_back(size); | ||
| 111 | } | ||
| 112 | 129 | ||
| 113 | // Sortieren | 130 | // Sortieren |
| 114 | ranges::sort(sizes, greater<>()); | 131 | nth_element(sizes.begin(), sizes.begin() + 3, sizes.end(), greater<>()); |
| 115 | 132 | ||
| 116 | cout << "Part 1: " << sizes[0] * sizes[1] * sizes[2] << '\n'; | 133 | cout << "Part 1: " << sizes[0] * sizes[1] * sizes[2] << '\n'; |
| 117 | } | 134 | } |
| @@ -119,25 +136,17 @@ part1(const vector<Pos>& list) | |||
| 119 | void | 136 | void |
| 120 | part2(const vector<Pos>& list) | 137 | part2(const vector<Pos>& list) |
| 121 | { | 138 | { |
| 122 | using Dist = tuple<double, size_t, size_t>; // (Distanz, Von, Nach) | 139 | const auto dists = get_distances(list); |
| 123 | |||
| 124 | // Distanzen paarweise erfassen... | ||
| 125 | vector<Dist> dists; | ||
| 126 | for ( size_t i = 0; i != list.size(); ++i ) { | ||
| 127 | for ( size_t j = i + 1; j != list.size(); ++j ) { | ||
| 128 | dists.emplace_back(get_distance(list[i], list[j]), i, j); | ||
| 129 | } | ||
| 130 | } | ||
| 131 | |||
| 132 | // ... und nach Distanz sortieren | ||
| 133 | ranges::sort(dists); | ||
| 134 | 140 | ||
| 135 | UnionFind unionFind(list.size()); | 141 | UnionFind unionFind(list.size()); |
| 136 | 142 | ||
| 137 | size_t count = 1; | 143 | // Alle Paare verbinden ... |
| 144 | size_t unions = 0; | ||
| 138 | for ( auto [dist, a, b]: dists ) { | 145 | for ( auto [dist, a, b]: dists ) { |
| 139 | if ( unionFind.unite(a, b) ) { | 146 | if ( unionFind.unite(a, b) ) { |
| 140 | if ( ++count == list.size() ) { | 147 | // ... beim Letzten abbrechen |
| 148 | ++unions; | ||
| 149 | if ( unions == list.size() - 1 ) { | ||
| 141 | cout << "Part 2: " << get<0>(list[a]) * get<0>(list[b]) << '\n'; | 150 | cout << "Part 2: " << get<0>(list[a]) * get<0>(list[b]) << '\n'; |
| 142 | return; | 151 | return; |
| 143 | } | 152 | } |
