aboutsummaryrefslogtreecommitdiff
path: root/2017/src/day20.cpp
diff options
context:
space:
mode:
authorThomas Schmucker <ts@its1.de>2025-11-02 21:41:58 +0100
committerThomas Schmucker <ts@its1.de>2025-11-02 21:41:58 +0100
commit756f22d58bb198b8f34589c112e1003614ccdcd6 (patch)
tree4cdeba335f1ea67f7ead9e9f763ba1c3c206fc4d /2017/src/day20.cpp
parentfcbb722bd4c5ca2bd34a7cf9c0ba48f2f955da13 (diff)
downloadadvent-of-code-756f22d58bb198b8f34589c112e1003614ccdcd6.tar.gz
advent-of-code-756f22d58bb198b8f34589c112e1003614ccdcd6.tar.bz2
advent-of-code-756f22d58bb198b8f34589c112e1003614ccdcd6.zip
aoc 2017, days 1-20
Diffstat (limited to '2017/src/day20.cpp')
-rw-r--r--2017/src/day20.cpp162
1 files changed, 162 insertions, 0 deletions
diff --git a/2017/src/day20.cpp b/2017/src/day20.cpp
new file mode 100644
index 0000000..fd09535
--- /dev/null
+++ b/2017/src/day20.cpp
@@ -0,0 +1,162 @@
1#include <filesystem>
2#include <fstream>
3#include <iostream>
4#include <map>
5#include <string>
6#include <vector>
7
8using namespace std;
9
10namespace {
11
12using point_type = tuple<long, long, long>;
13using particle_type = tuple<point_type, point_type, point_type>;
14
15#if 0
16ostream&
17operator<<(ostream& strm, const point_type& point)
18{
19 const auto [x, y, z] = point;
20 strm << '<' << x << ',' << y << ',' << z << '>';
21 return strm;
22}
23
24ostream&
25operator<<(ostream& strm, const particle_type& particle)
26{
27 const auto [pos, velo, accel] = particle;
28 strm << "p=" << pos << ", v=" << velo << ", a=" << accel;
29 return strm;
30}
31#endif
32
33vector<long>
34split(const string& line, const string& delimiters)
35{
36 vector<long> result;
37
38 size_t start = 0;
39 size_t end = 0;
40
41 while ( (end = line.find_first_of(delimiters, start)) != string::npos ) {
42 if ( end != start ) {
43 result.emplace_back(stol(line.substr(start, end - start)));
44 }
45
46 start = end + 1;
47 }
48
49 if ( start != line.size() ) {
50 result.emplace_back(stol(line.substr(start)));
51 }
52
53 return result;
54}
55
56vector<particle_type>
57read_file(const filesystem::path& filename)
58{
59 ifstream file{ filename };
60 vector<particle_type> data;
61
62 for ( string line; getline(file, line); ) {
63 auto parts = split(line, "p=<>,va ");
64
65 point_type position{ parts.at(0), parts.at(1), parts.at(2) };
66 point_type velocity{ parts.at(3), parts.at(4), parts.at(5) };
67 point_type acceleration{ parts.at(6), parts.at(7), parts.at(8) };
68
69 data.emplace_back(position, velocity, acceleration);
70 }
71
72 return data;
73}
74
75point_type
76add(const point_type& lhs, const point_type& rhs)
77{
78 return { get<0>(lhs) + get<0>(rhs), get<1>(lhs) + get<1>(rhs), get<2>(lhs) + get<2>(rhs) };
79}
80
81void
82update(particle_type& particle)
83{
84 auto [pos, vel, acc] = particle;
85
86 vel = add(vel, acc);
87 pos = add(pos, vel);
88
89 particle = { pos, vel, acc };
90}
91
92long
93distance(const point_type& point)
94{
95 return abs(get<0>(point)) + abs(get<1>(point)) + abs(get<2>(point));
96}
97
98void
99part1(vector<particle_type> particles)
100{
101 size_t current_min_index = particles.size();
102
103 for ( int round = 0; round != 10000; ++round ) {
104 // Alle updaten
105 ranges::for_each(particles, update);
106
107 long step_min_dist = numeric_limits<long>::max();
108 size_t step_min_index = current_min_index;
109
110 // kleinste Distanz suchen
111 for ( size_t i = 0; i != particles.size(); ++i ) {
112 auto min_dist = distance(get<0>(particles.at(i)));
113
114 if ( min_dist < step_min_dist ) {
115 step_min_dist = min_dist;
116 step_min_index = i;
117 }
118 }
119
120 // Prüfen, ob stabil
121 if ( step_min_index != current_min_index ) {
122 current_min_index = step_min_index;
123 round = 0;
124 }
125 }
126
127 cout << "Part1: " << current_min_index << '\n';
128}
129
130void
131part2(vector<particle_type> particles)
132{
133 for ( int round = 0; round != 10000; ++round ) {
134 // Alle updaten
135 ranges::for_each(particles, update);
136
137 map<point_type, size_t> collision_counter;
138
139 for ( const auto& [pos, vel, accl]: particles ) {
140 collision_counter[pos]++;
141 }
142
143 for ( const auto& [pos, count]: collision_counter ) {
144 if ( count > 1 ) {
145 erase_if(particles, [&pos](const auto& particle) { return get<0>(particle) == pos; });
146 round = 0;
147 }
148 }
149 }
150
151 cout << "Part2: " << particles.size() << '\n';
152}
153
154} // namespace
155
156int
157main()
158{
159 auto data = read_file("data/day20.txt");
160 part1(data);
161 part2(data);
162}