diff options
| author | Thomas Schmucker <ts@its1.de> | 2025-11-02 21:41:58 +0100 |
|---|---|---|
| committer | Thomas Schmucker <ts@its1.de> | 2025-11-02 21:41:58 +0100 |
| commit | 756f22d58bb198b8f34589c112e1003614ccdcd6 (patch) | |
| tree | 4cdeba335f1ea67f7ead9e9f763ba1c3c206fc4d /2017/src/day20.cpp | |
| parent | fcbb722bd4c5ca2bd34a7cf9c0ba48f2f955da13 (diff) | |
| download | advent-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.cpp | 162 |
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 | |||
| 8 | using namespace std; | ||
| 9 | |||
| 10 | namespace { | ||
| 11 | |||
| 12 | using point_type = tuple<long, long, long>; | ||
| 13 | using particle_type = tuple<point_type, point_type, point_type>; | ||
| 14 | |||
| 15 | #if 0 | ||
| 16 | ostream& | ||
| 17 | operator<<(ostream& strm, const point_type& point) | ||
| 18 | { | ||
| 19 | const auto [x, y, z] = point; | ||
| 20 | strm << '<' << x << ',' << y << ',' << z << '>'; | ||
| 21 | return strm; | ||
| 22 | } | ||
| 23 | |||
| 24 | ostream& | ||
| 25 | operator<<(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 | |||
| 33 | vector<long> | ||
| 34 | split(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 | |||
| 56 | vector<particle_type> | ||
| 57 | read_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 | |||
| 75 | point_type | ||
| 76 | add(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 | |||
| 81 | void | ||
| 82 | update(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 | |||
| 92 | long | ||
| 93 | distance(const point_type& point) | ||
| 94 | { | ||
| 95 | return abs(get<0>(point)) + abs(get<1>(point)) + abs(get<2>(point)); | ||
| 96 | } | ||
| 97 | |||
| 98 | void | ||
| 99 | part1(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 | |||
| 130 | void | ||
| 131 | part2(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 | |||
| 156 | int | ||
| 157 | main() | ||
| 158 | { | ||
| 159 | auto data = read_file("data/day20.txt"); | ||
| 160 | part1(data); | ||
| 161 | part2(data); | ||
| 162 | } | ||
