Add solution for "Day 22: Monkey Market", part 2

This commit is contained in:
2025-06-10 21:27:09 +02:00
parent f025896e84
commit f312893ed1
4 changed files with 60 additions and 2 deletions

View File

@@ -15,6 +15,11 @@
#include <aoc/MonkeyMarket.hpp>
MonkeyMarket::MonkeyMarket(const int inputFileNameSuffix)
: Solver{ inputFileNameSuffix }, nBuyers_{ 0 }, sequenceResults_{}
{
}
const std::string MonkeyMarket::getPuzzleName() const
{
return "Monkey Market";
@@ -28,13 +33,35 @@ const int MonkeyMarket::getPuzzleDay() const
void MonkeyMarket::processDataLine(const std::string& line)
{
uint64_t n{ std::stoull(line) };
uint64_t price{ n % getPriceModulo() };
uint64_t change;
uint64_t newPrice;
uint64_t rollingChangeSequence{ 0 };
for (int i = 0; i < getNSecretNumbers(); i++)
{
n = ((n << 6) ^ n) & getPruneValue();
n = (n >> 5) ^ n;
n = ((n << 11) ^ n) & getPruneValue();
newPrice = n % getPriceModulo();
change = getPriceModulo() + newPrice - price;
price = newPrice;
updateNewRollingChangeSequence(rollingChangeSequence, change);
if (i >= 3)
{
const auto& [it, success] = sequenceResults_.insert({ rollingChangeSequence, { newPrice, nBuyers_ } });
if (!success && it->second.second < nBuyers_)
{
it->second.first += newPrice;
it->second.second = nBuyers_;
if (it->second.first > part2)
{
part2 = it->second.first;
}
}
}
}
part1 += n;
nBuyers_++;
}
void MonkeyMarket::finish()
@@ -50,3 +77,15 @@ constexpr uint64_t MonkeyMarket::getPruneValue()
{
return 16777215;
}
constexpr int MonkeyMarket::getPriceModulo()
{
return 10;
}
void MonkeyMarket::updateNewRollingChangeSequence(uint64_t& rollingChangeSequence, const uint64_t change)
{
// Prices vary from -9 to 9, so we can store the price change plus the price modulo of 10, which is a number between
// 1 and 19, as a 5-bit part in this rolling change sequence number and use it as the key in the sequence map.
rollingChangeSequence = ((rollingChangeSequence << 5) & 0b11111111111111111111) | change;
}