diff options
| author | Thomas Schmucker <ts@its1.de> | 2025-01-02 17:12:07 +0100 |
|---|---|---|
| committer | Thomas Schmucker <ts@its1.de> | 2025-01-02 17:12:07 +0100 |
| commit | 3a236e5e3c301abe2a1abe6ae072b3aa81a3cfe4 (patch) | |
| tree | f07da71c2101614810e836e94ae723d2e1b35358 /2024/src | |
| parent | 9098c9d0d9922f54b3ad9414151604402b8e9c44 (diff) | |
| download | advent-of-code-3a236e5e3c301abe2a1abe6ae072b3aa81a3cfe4.tar.gz advent-of-code-3a236e5e3c301abe2a1abe6ae072b3aa81a3cfe4.tar.bz2 advent-of-code-3a236e5e3c301abe2a1abe6ae072b3aa81a3cfe4.zip | |
aoc 2024, day 24, cleanup
Diffstat (limited to '2024/src')
| -rw-r--r-- | 2024/src/day24.cpp | 87 |
1 files changed, 38 insertions, 49 deletions
diff --git a/2024/src/day24.cpp b/2024/src/day24.cpp index 3f252a1..c2bd505 100644 --- a/2024/src/day24.cpp +++ b/2024/src/day24.cpp | |||
| @@ -114,15 +114,6 @@ part1(const tuple<map<string, unsigned long>, map<string, tuple<string, string, | |||
| 114 | cout << value << endl; | 114 | cout << value << endl; |
| 115 | } | 115 | } |
| 116 | 116 | ||
| 117 | string | ||
| 118 | make_wire(char chr, unsigned long num) | ||
| 119 | { | ||
| 120 | static const size_t MAX_LEN = 10; | ||
| 121 | array<char, MAX_LEN> tmp{}; | ||
| 122 | snprintf(tmp.data(), tmp.size(), "%c%02lu", chr, num); // NOLINT | ||
| 123 | return tmp.data(); | ||
| 124 | } | ||
| 125 | |||
| 126 | class RippleCarryAdder { | 117 | class RippleCarryAdder { |
| 127 | public: | 118 | public: |
| 128 | explicit RippleCarryAdder(const tuple<map<string, unsigned long>, map<string, tuple<string, string, string>>>& data) | 119 | explicit RippleCarryAdder(const tuple<map<string, unsigned long>, map<string, tuple<string, string, string>>>& data) |
| @@ -131,12 +122,6 @@ public: | |||
| 131 | { | 122 | { |
| 132 | } | 123 | } |
| 133 | 124 | ||
| 134 | RippleCarryAdder(const map<string, tuple<string, string, string>>& deps, unsigned long x_value, unsigned long y_value) | ||
| 135 | : deps_(deps) | ||
| 136 | { | ||
| 137 | build_inputs(x_value, y_value); | ||
| 138 | } | ||
| 139 | |||
| 140 | void swap_wire(const string& lhs, const string& rhs) | 125 | void swap_wire(const string& lhs, const string& rhs) |
| 141 | { | 126 | { |
| 142 | swap(deps_.at(lhs), deps_.at(rhs)); | 127 | swap(deps_.at(lhs), deps_.at(rhs)); |
| @@ -197,6 +182,14 @@ public: | |||
| 197 | } | 182 | } |
| 198 | 183 | ||
| 199 | private: | 184 | private: |
| 185 | static string make_wire(char chr, unsigned long num) | ||
| 186 | { | ||
| 187 | static const size_t MAX_LEN = 10; | ||
| 188 | array<char, MAX_LEN> tmp{}; | ||
| 189 | snprintf(tmp.data(), tmp.size(), "%c%02lu", chr, num); // NOLINT | ||
| 190 | return tmp.data(); | ||
| 191 | } | ||
| 192 | |||
| 200 | void build_inputs(unsigned long x_value, unsigned long y_value) | 193 | void build_inputs(unsigned long x_value, unsigned long y_value) |
| 201 | { | 194 | { |
| 202 | inputs_.clear(); | 195 | inputs_.clear(); |
| @@ -269,54 +262,50 @@ part2(const tuple<map<string, unsigned long>, map<string, tuple<string, string, | |||
| 269 | set<string> solution; | 262 | set<string> solution; |
| 270 | 263 | ||
| 271 | for ( auto bit = 0UL; bit != MAX_BITS; ++bit ) { | 264 | for ( auto bit = 0UL; bit != MAX_BITS; ++bit ) { |
| 272 | const auto x_value = 1UL << bit; // (1UL << (bit+1)) - 1; | 265 | const auto x_value = 1UL << bit; |
| 273 | const auto y_value = 0UL << bit; | 266 | const auto y_value = 0UL; |
| 274 | 267 | ||
| 275 | if ( !rca.eval_z(x_value, y_value) ) { | 268 | if ( !rca.eval_z(x_value, y_value) ) { |
| 276 | return; | 269 | return; |
| 277 | } | 270 | } |
| 278 | 271 | ||
| 279 | const auto failed_bits = rca.test(x_value, y_value); | 272 | const auto failed_bits = rca.test(x_value, y_value); |
| 280 | if ( !failed_bits.empty() ) { | 273 | if ( failed_bits.empty() ) { |
| 281 | set<string> candidates; | 274 | continue; |
| 282 | for ( const auto& wire: failed_bits ) { | 275 | } |
| 283 | rca.collect(wire, candidates); | ||
| 284 | } | ||
| 285 | 276 | ||
| 286 | const vector<string> foo{ candidates.begin(), candidates.end() }; | 277 | set<string> unique_candidates; |
| 278 | for ( const auto& wire: failed_bits ) { | ||
| 279 | rca.collect(wire, unique_candidates); | ||
| 280 | } | ||
| 287 | 281 | ||
| 288 | for ( auto i = foo.begin(); i != foo.end(); ++i ) { | 282 | const vector<string> candidates{ unique_candidates.begin(), unique_candidates.end() }; |
| 289 | for ( auto j = i + 1; j != foo.end(); ++j ) { | ||
| 290 | auto do_test = [&](unsigned long lhs, unsigned long rhs) -> bool { | ||
| 291 | RippleCarryAdder rca_tester{ data }; | ||
| 292 | 283 | ||
| 293 | rca_tester.swap_wire(*i, *j); | 284 | for ( auto i = candidates.begin(); i != candidates.end(); ++i ) { |
| 285 | for ( auto j = i + 1; j != candidates.end(); ++j ) { | ||
| 286 | auto do_test = [&](const tuple<unsigned long, unsigned long>& test_value) -> bool { | ||
| 287 | const auto [lhs, rhs] = test_value; | ||
| 294 | 288 | ||
| 295 | if ( !rca_tester.eval_z(lhs, rhs) ) { | 289 | RippleCarryAdder rca_tester{ data }; |
| 296 | return false; | ||
| 297 | } | ||
| 298 | return rca_tester.test(lhs, rhs).empty(); | ||
| 299 | }; | ||
| 300 | 290 | ||
| 301 | if ( do_test(x_value, y_value) ) { | 291 | rca_tester.swap_wire(*i, *j); |
| 302 | const auto x_value2 = 7UL << (bit - 1); | ||
| 303 | const auto y_value2 = 3UL << (bit - 1); | ||
| 304 | 292 | ||
| 305 | if ( do_test(x_value2, y_value2) ) { | 293 | if ( !rca_tester.eval_z(lhs, rhs) ) { |
| 306 | const auto x_value3 = 1UL << bit; | 294 | return false; |
| 307 | const auto y_value3 = 1UL << bit; | 295 | } |
| 296 | return rca_tester.test(lhs, rhs).empty(); | ||
| 297 | }; | ||
| 308 | 298 | ||
| 309 | if ( do_test(x_value3, y_value3) ) { | 299 | const vector<tuple<unsigned long, unsigned long>> test_values = { |
| 310 | const auto x_value4 = 5UL << (bit - 1); | 300 | { x_value, y_value }, |
| 311 | const auto y_value4 = 3UL << (bit - 1); | 301 | { 7UL << (bit - 1), 3UL << (bit - 1) }, |
| 302 | { 1UL << bit, 1UL << bit }, | ||
| 303 | { 5UL << (bit - 1), 3UL << (bit - 1) } | ||
| 304 | }; | ||
| 312 | 305 | ||
| 313 | if ( do_test(x_value4, y_value4) ) { | 306 | if ( ranges::all_of(test_values, do_test) ) { |
| 314 | solution.insert(*i); | 307 | solution.insert(*i); |
| 315 | solution.insert(*j); | 308 | solution.insert(*j); |
| 316 | } | ||
| 317 | } | ||
| 318 | } | ||
| 319 | } | ||
| 320 | } | 309 | } |
| 321 | } | 310 | } |
| 322 | } | 311 | } |
