diff --git a/src/2025/Day10.cpp b/src/2025/Day10.cpp index 8c3adc3..db39f4c 100644 --- a/src/2025/Day10.cpp +++ b/src/2025/Day10.cpp @@ -80,6 +80,126 @@ namespace y2025::day10 return minSolution; } + bool IsGoal(const std::vector& joltageTarget) + { + for (auto joltage : joltageTarget) + { + if (joltage != 0) + return false; + } + return true; + } + + bool IsValid(const std::vector& joltageTarget) + { + for (auto joltage : joltageTarget) + { + if (joltage < 0) + return false; + } + return true; + } + + std::vector> GetButtonsList(const Machine& machine, + uint64_t parity, + int button, + const std::vector& buttons) + { + std::vector> result; + if (parity == 0) + { + result.emplace_back(buttons); + } + + for (int i = button; i < machine.buttons.size(); i++) + { + uint64_t newParity = parity; + for (auto b : machine.buttons[i]) + { + newParity ^= 1 << b; + } + std::vector newButtons = buttons; + newButtons.emplace_back(i); + std::vector> buttonsList = GetButtonsList(machine, newParity, i + 1, newButtons); + for (const auto& validButtons : buttonsList) + { + result.emplace_back(validButtons); + } + } + return result; + } + + std::vector> GetButtonsList(const Machine& machine, + uint64_t parity, + std::map>>& memoizationButtons) + { + auto it = memoizationButtons.find(parity); + if (it != memoizationButtons.end()) + return it->second; + + auto paths = GetButtonsList(machine, parity, 0, {}); + + memoizationButtons[parity] = paths; + return paths; + } + + std::vector GetNewJoltage(const Machine& machine, + const std::vector& buttons, + const std::vector& joltage) + { + std::vector newJoltage = joltage; + for (auto b : buttons) + { + for (int index : machine.buttons[b]) + { + newJoltage[index]--; + } + } + for (auto& j : newJoltage) + { + j /= 2; + } + return newJoltage; + } + + uint64_t GetParity(const std::vector& joltage) + { + uint64_t parity{0}; + for (int i = 0; i < joltage.size(); i++) + { + parity |= (joltage[i] % 2 == 1) << i; + } + return parity; + } + + int64_t Minimum(const Machine& machine, + const std::vector& targetJoltage, + std::map, int64_t>& memoization, + std::map>>& memoizationButtons) + { + if (IsGoal(targetJoltage)) + return 0; + + auto it = memoization.find(targetJoltage); + if (it != memoization.end()) + return it->second; + + uint64_t parity = GetParity(targetJoltage); + auto buttonsList = GetButtonsList(machine, parity, memoizationButtons); + + int64_t minimum = std::numeric_limits::max(); + for (const auto& buttons : buttonsList) + { + std::vector newJoltage = GetNewJoltage(machine, buttons, targetJoltage); + if (!IsValid(newJoltage)) + continue; + int64_t result = Minimum(machine, newJoltage, memoization, memoizationButtons); + minimum = std::min(minimum, 2 * result + (int64_t)buttons.size()); + } + memoization[targetJoltage] = minimum; + return minimum; + } + OUTPUT1(input) { int total = 0; @@ -94,7 +214,13 @@ namespace y2025::day10 OUTPUT2(input) { - // Solved in python/z3 - return isExample ? 33 : 16613; + int64_t total = 0; + for (auto machine : input) + { + std::map, int64_t> memoization; + std::map>> memoizationButtons; + total += Minimum(machine, machine.joltage, memoization, memoizationButtons); + } + return total; } }