diff --git a/README.md b/README.md index 3d2ceca..c82fddb 100644 --- a/README.md +++ b/README.md @@ -50,6 +50,12 @@ My implementation uses an ordering matrix (a two-dimensional boolean array) to t The algorithm starts at the trail ends (the `9`'s) and searches all options from there downwards until trailheads are reached. For each visited map location, it tracks unique reachable end points (for part 1) and number of possible paths to end points (for part 2). These values are accumulated, if during the search the same map location is encountered again. +### Day 11: Plutonian Pebbles + +:mag_right: Puzzle: , :white_check_mark: Solver: [`PlutonianPebbles.cpp`](AdventOfCode2024/PlutonianPebbles.cpp) + +Since the order of the pebbles does not actually matter, we can simply blink from one line of pebbles to the next and count only cardinalities of each number in the current line. + ## Thanks * [Alexander Brouwer](https://github.com/Bromvlieg) for getting the project set up with CMake. diff --git a/include/aoc/PlutonianPebbles.hpp b/include/aoc/PlutonianPebbles.hpp index 8399aa3..9680f68 100644 --- a/include/aoc/PlutonianPebbles.hpp +++ b/include/aoc/PlutonianPebbles.hpp @@ -28,9 +28,11 @@ class PlutonianPebbles : public Solver virtual void processDataLine(const std::string& line) override; virtual void finish() override; private: - static constexpr int getNBlinks(); + static constexpr int getNBlinksPart1(); + static constexpr int getNBlinksPart2(); std::map> blinkMap_{}; - void addPebble(std::map& pebbles, const long long int pebbleNumber, int cardinality); + void addPebble(std::map& pebbles, const long long int pebbleNumber, + long long int cardinality); void addNextBlinkNumbers(const long long int pebbleNumber, std::vector& nextBlinkNumbers); int getNNextBlinkNumbers(const long long int pebbleNumber) const; }; diff --git a/src/PlutonianPebbles.cpp b/src/PlutonianPebbles.cpp index 7ee076f..2a52ced 100644 --- a/src/PlutonianPebbles.cpp +++ b/src/PlutonianPebbles.cpp @@ -31,9 +31,9 @@ const std::string PlutonianPebbles::getInputFileName() const void PlutonianPebbles::processDataLine(const std::string& line) { // Maps pebble numbers before the blink to their cardinality. - auto currentPebbles = std::make_shared>(); + auto currentPebbles = std::make_shared>(); // Maps pebble numbers after the blink to their cardinality. - std::shared_ptr> nextBlinkPebbles; + std::shared_ptr> nextBlinkPebbles; // Adds initial pebbles numbers. std::istringstream lineStream{ line }; @@ -44,10 +44,10 @@ void PlutonianPebbles::processDataLine(const std::string& line) } // Processes the blinks. - for (int i = getNBlinks(); i > 1; i--) + for (int i = getNBlinksPart2(); i > 1; i--) { // Maps pebble numbers after the blink to their cardinality. - nextBlinkPebbles = std::make_shared>(); + nextBlinkPebbles = std::make_shared>(); for (const auto& pebble : *currentPebbles) { @@ -64,21 +64,31 @@ void PlutonianPebbles::processDataLine(const std::string& line) } } + if (i == getNBlinksPart2() - getNBlinksPart1() + 1) + { + for (const auto& blinkNumber : *currentPebbles) + { + // The number is guaranteed to be in blinkMap_ already. + auto hit = blinkMap_.find(blinkNumber.first); + part1 += blinkNumber.second * hit->second.size(); + } + } + currentPebbles = nextBlinkPebbles; } - for (const auto nextBlinkNumber : *nextBlinkPebbles) + for (const auto& nextBlinkNumber : *nextBlinkPebbles) { // In the last step we only care about cardinalities, not the actual new pebble numbers, so we use // getNNextBlinkNumbers() instead of addNextBlinkNumbers(). auto hit = blinkMap_.find(nextBlinkNumber.first); if (hit == blinkMap_.end()) { - part1 += nextBlinkNumber.second * getNNextBlinkNumbers(nextBlinkNumber.first); + part2 += nextBlinkNumber.second * getNNextBlinkNumbers(nextBlinkNumber.first); } else { - part1 += nextBlinkNumber.second * hit->second.size(); + part2 += nextBlinkNumber.second * hit->second.size(); } } } @@ -87,13 +97,18 @@ void PlutonianPebbles::finish() { } -constexpr int PlutonianPebbles::getNBlinks() +constexpr int PlutonianPebbles::getNBlinksPart1() { return 25; } -void PlutonianPebbles::addPebble(std::map& pebbles, const long long int pebbleNumber, - int cardinality) +constexpr int PlutonianPebbles::getNBlinksPart2() +{ + return 75; +} + +void PlutonianPebbles::addPebble(std::map& pebbles, const long long int pebbleNumber, + long long int cardinality) { auto hit = pebbles.find(pebbleNumber); if (hit == pebbles.end()) diff --git a/tests/src/TestCases.cpp b/tests/src/TestCases.cpp index 75a7e87..f7a9581 100644 --- a/tests/src/TestCases.cpp +++ b/tests/src/TestCases.cpp @@ -124,11 +124,11 @@ TEST_CASE("[PlutonianPebblesTests]") TestContext test; SECTION("FullData") { - test.run(std::make_unique(), 220999, 0, test.getInputPaths()); + test.run(std::make_unique(), 220999, 261936432123724, test.getInputPaths()); } SECTION("ExampleData") { - test.run(std::make_unique(), 55312, 0, test.getExampleInputPaths()); + test.run(std::make_unique(), 55312, 65601038650482, test.getExampleInputPaths()); } }