// 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 #include #include const std::string BridgeRepair::getPuzzleName() const { return "Bridge Repair"; } const int BridgeRepair::getPuzzleDay() const { return 7; } void BridgeRepair::processDataLine(const std::string& line) { std::istringstream stream{ line }; long long int testValue; char colon; int calibrationNumber; // Calibration numbers are a pair of an actual calibration number and its precomputed smallest larger power of 10. // The precomputed numbers are used to facilitate the "concatenate" operator. std::vector> calibrationNumbers{}; stream >> testValue >> colon; while (stream >> calibrationNumber) { // Skips the precomputation for the first calibration numbers. int pow10{ 0 }; if (!calibrationNumbers.empty()) { pow10 = Math::ipow(10, static_cast(floor(log10(calibrationNumber))) + 1); } calibrationNumbers.push_back({ calibrationNumber, pow10 }); } if (testCalibration(testValue, calibrationNumbers, 1, false, calibrationNumbers[0].first)) { part1 += testValue; part2 += testValue; } else if (testCalibration(testValue, calibrationNumbers, 1, true, calibrationNumbers[0].first)) { part2 += testValue; } } void BridgeRepair::finish() { } bool BridgeRepair::testCalibration(const long long int testValue, const std::vector>& calibrationNumbers, const size_t currentIndex, const bool allowConcatenation, const long long int accumulatedTestValue) { if (testValue >= accumulatedTestValue && currentIndex < calibrationNumbers.size()) { size_t nextIndex{ currentIndex + 1 }; long long int nextCalibrationNumber{ calibrationNumbers[currentIndex].first }; // Recursively tries the ||, *, and + operators. if ((allowConcatenation && testCalibration(testValue, calibrationNumbers, nextIndex, allowConcatenation, accumulatedTestValue * calibrationNumbers[currentIndex].second + calibrationNumbers[currentIndex].first)) || testCalibration(testValue, calibrationNumbers, nextIndex, allowConcatenation, accumulatedTestValue * calibrationNumbers[currentIndex].first) || testCalibration(testValue, calibrationNumbers, nextIndex, allowConcatenation, accumulatedTestValue + calibrationNumbers[currentIndex].first)) { return true; } } else if (testValue == accumulatedTestValue) { return true; } return false; }