// Solutions to the Advent Of Code 2024. // Copyright (C) 2025 Stefan Müller // // This program is free software: you can redistribute it and/or modify it under // the terms of the GNU General Public License as published by the Free Software // Foundation, either version 3 of the License, or (at your option) any later // version. // // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS // FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along with // this program. If not, see . #include #include const std::string ClawContraption::getPuzzleName() const { return "Claw Contraption"; } const int ClawContraption::getPuzzleDay() const { return 13; } void ClawContraption::processDataLine(const std::string& line) { if (!line.empty()) { std::istringstream stream{ line }; std::string token; char c; int x; int y; stream >> token; if (token == "Button") { stream >> c; std::getline(stream, token, '+'); stream >> x; std::getline(stream, token, '+'); stream >> y; if (c == 'A') { buttonA_ = { x, y }; } else { buttonB_ = { x, y }; } } else { std::getline(stream, token, '='); stream >> x; std::getline(stream, token, '='); stream >> y; part1 += calcTokenCost(buttonA_, buttonB_, { x, y }, 0); part2 += calcTokenCost(buttonA_, buttonB_, { x, y }, getConversionCorrection()); } } } void ClawContraption::finish() { } constexpr int ClawContraption::getNMaxButtonPushes() { return 100; } constexpr int ClawContraption::getButtonACost() { return 3; } constexpr int ClawContraption::getButtonBCost() { return 1; } constexpr long long int ClawContraption::getConversionCorrection() { return 10000000000000; } long long int ClawContraption::calcTokenCost(const Point2& buttonA, const Point2& buttonB, const Point2& prize, const long long int offset) { long long int p{ (prize.y + offset) * buttonB.x - (prize.x + offset) * buttonB.y }; long long int q{ buttonA.y * buttonB.x - buttonA.x * buttonB.y }; long long int a{ p / q }; if (a * q != p || (offset == 0 && a > getNMaxButtonPushes())) { return 0; } long long int r{ prize.x + offset - a * buttonA.x }; long long int b{ r / buttonB.x }; if (b * buttonB.x != r || (offset == 0 && b > getNMaxButtonPushes())) { return 0; } return a * getButtonACost() + b * getButtonBCost(); }