Add solution for "Day 11: Plutonian Pebbles", part 2
This commit is contained in:
parent
eaee3bd347
commit
21279a97a6
|
@ -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: <https://adventofcode.com/2024/day/11>, :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.
|
||||
|
|
|
@ -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<long long int, std::vector<long long int>> blinkMap_{};
|
||||
void addPebble(std::map<long long int, int>& pebbles, const long long int pebbleNumber, int cardinality);
|
||||
void addPebble(std::map<long long int, long long int>& pebbles, const long long int pebbleNumber,
|
||||
long long int cardinality);
|
||||
void addNextBlinkNumbers(const long long int pebbleNumber, std::vector<long long int>& nextBlinkNumbers);
|
||||
int getNNextBlinkNumbers(const long long int pebbleNumber) const;
|
||||
};
|
||||
|
|
|
@ -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<std::map<long long int, int>>();
|
||||
auto currentPebbles = std::make_shared<std::map<long long int, long long int>>();
|
||||
// Maps pebble numbers after the blink to their cardinality.
|
||||
std::shared_ptr<std::map<long long int, int>> nextBlinkPebbles;
|
||||
std::shared_ptr<std::map<long long int, long long int>> 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<std::map<long long int, int>>();
|
||||
nextBlinkPebbles = std::make_shared<std::map<long long int, long long int>>();
|
||||
|
||||
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<long long int, int>& pebbles, const long long int pebbleNumber,
|
||||
int cardinality)
|
||||
constexpr int PlutonianPebbles::getNBlinksPart2()
|
||||
{
|
||||
return 75;
|
||||
}
|
||||
|
||||
void PlutonianPebbles::addPebble(std::map<long long int, long long int>& pebbles, const long long int pebbleNumber,
|
||||
long long int cardinality)
|
||||
{
|
||||
auto hit = pebbles.find(pebbleNumber);
|
||||
if (hit == pebbles.end())
|
||||
|
|
|
@ -124,11 +124,11 @@ TEST_CASE("[PlutonianPebblesTests]")
|
|||
TestContext test;
|
||||
SECTION("FullData")
|
||||
{
|
||||
test.run(std::make_unique<PlutonianPebbles>(), 220999, 0, test.getInputPaths());
|
||||
test.run(std::make_unique<PlutonianPebbles>(), 220999, 261936432123724, test.getInputPaths());
|
||||
}
|
||||
SECTION("ExampleData")
|
||||
{
|
||||
test.run(std::make_unique<PlutonianPebbles>(), 55312, 0, test.getExampleInputPaths());
|
||||
test.run(std::make_unique<PlutonianPebbles>(), 55312, 65601038650482, test.getExampleInputPaths());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue