aboutsummaryrefslogtreecommitdiff
path: root/2025
diff options
context:
space:
mode:
Diffstat (limited to '2025')
-rw-r--r--2025/src/day08.cpp122
1 files changed, 122 insertions, 0 deletions
diff --git a/2025/src/day08.cpp b/2025/src/day08.cpp
new file mode 100644
index 0000000..366d827
--- /dev/null
+++ b/2025/src/day08.cpp
@@ -0,0 +1,122 @@
1#include <cmath>
2#include <filesystem>
3#include <fstream>
4#include <iostream>
5#include <map>
6#include <tuple>
7#include <vector>
8
9using namespace std;
10
11namespace {
12
13class UnionFind {
14public:
15 explicit UnionFind(size_t size)
16 : parent_(size)
17 {
18 for ( size_t i = 0; i != size; ++i ) {
19 parent_[i] = i;
20 }
21 }
22
23 size_t find(size_t n)
24 {
25 if ( parent_[n] != n ) {
26 parent_[n] = find(parent_[n]);
27 }
28 return parent_[n];
29 }
30
31 void unite(size_t a, size_t b)
32 {
33 a = find(a);
34 b = find(b);
35
36 parent_[b] = a;
37 }
38
39private:
40 vector<size_t> parent_;
41};
42
43using Pos = tuple<long, long, long>;
44
45vector<Pos>
46read_file(const filesystem::path& filename)
47{
48 ifstream file{ filename };
49
50 vector<Pos> list;
51
52 long x{};
53 long y{};
54 long z{};
55 char ch{};
56
57 while ( file >> x >> ch >> y >> ch >> z ) {
58 list.emplace_back(x, y, z);
59 }
60
61 return list;
62}
63
64double
65get_distance(const Pos& pos1, const Pos& pos2)
66{
67 const auto [x1, y1, z1] = pos1;
68 const auto [x2, y2, z2] = pos2;
69
70 return hypot(x1 - x2, y1 - y2, z1 - z2);
71}
72
73void
74part1(const vector<Pos>& list)
75{
76 using Dist = tuple<double, size_t, size_t>; // (Distanz, Von, Nach)
77
78 // Distanzen paarweise erfassen...
79 vector<Dist> dists;
80 for ( size_t i = 0; i != list.size(); ++i ) {
81 for ( size_t j = i + 1; j != list.size(); ++j ) {
82 dists.emplace_back(get_distance(list[i], list[j]), i, j);
83 }
84 }
85
86 // ... und nach Distanz sortieren
87 ranges::sort(dists);
88
89 UnionFind unionFind(list.size());
90
91 // die kürzesten 1000 Elemente verbinden
92 for ( size_t i = 0; i != 1000; ++i ) {
93 const auto [dist, a, b] = dists[i];
94 unionFind.unite(a, b);
95 }
96
97 // die Längen der Verbindungen zählen
98 map<size_t, size_t> compSizes;
99 for ( size_t i = 0; i != list.size(); ++i ) {
100 compSizes[unionFind.find(i)]++;
101 }
102
103 // Größen finden
104 vector<size_t> sizes;
105 for ( const auto& [root, size]: compSizes ) {
106 sizes.emplace_back(size);
107 }
108
109 // Sortieren
110 ranges::sort(sizes, greater<>());
111
112 cout << "Part 1: " << sizes[0] * sizes[1] * sizes[2] << '\n';
113}
114
115} // namespace
116
117int
118main()
119{
120 auto data = read_file("data/day08.txt");
121 part1(data);
122}