#include #include #include #include #include #include #include #include #include #include #include #include #include #include struct IDRange { long leftRange; long rightRange; }; auto parseBanks(const std::string& filename) -> std::expected>, std::string> { std::ifstream inputF {filename}; if (!inputF){ return std::unexpected{"Some file open error.\n"}; } std::vector> banks{}; std::string bankLine{}; while(std::getline(inputF,bankLine)){ banks.emplace_back(bankLine | std::views::transform([](char c){ return c - '0';}) | std::ranges::to>()); } inputF.close(); return std::move(banks); } auto calculateJoltage(const std::vector& bank) -> long{ auto curIt = bank.begin(); auto rightIt = bank.end(); //int leftMax = 0; auto leftBound = bank.begin(); // First find biggest number with that is not the last while(curIt != rightIt-1){ if(*curIt > *leftBound ){ leftBound = curIt; } //std::println("Cur: {}, lMax: {}", *curIt, *leftBound); curIt++; } int rightMax = 0; while(leftBound != rightIt) { rightMax = std::max(rightMax, *rightIt); rightIt--; } std::println("LMax: {}, rMax: {}", *leftBound, rightMax); return (*leftBound)*10 +rightMax; } auto countJoltages(const std::vector>& banks) { long totalJoltage{}; for(const auto& bank : banks){ std::println("Bank: {}", bank); totalJoltage += calculateJoltage(bank); } return totalJoltage; } auto calculateJoltageP2(const std::vector& bank) -> long long{ const int TO_TAKE = 12; std::vector takenNumbers{}; auto curIt = bank.begin(); auto rightIt = bank.end(); auto leftBound = bank.begin(); while(takenNumbers.size() != TO_TAKE){ // First find biggest number with that is not in the last 12 while(curIt != (rightIt +1 - TO_TAKE + takenNumbers.size())){ if(*curIt > *leftBound ){ leftBound = curIt; } curIt++; } takenNumbers.push_back(*leftBound); curIt = leftBound+1; leftBound = curIt; } long long intRepr = std::ranges::fold_left(takenNumbers, 0, [](long long x, long long y) -> long long{ return (x*10) + y; }); return intRepr; } auto calculateJoltageP2_Optimized(const std::vector& bank) -> long long { const int TO_TAKE = 12; if (bank.size() < TO_TAKE) { return 0; } long long result = 0; auto current_start = bank.begin(); for (int i = 0; i < TO_TAKE; ++i) { int items_needed_after_this = (TO_TAKE - 1) - i; auto search_end = bank.end() - items_needed_after_this; auto max_it = std::max_element(current_start, search_end); result = (result * 10) + *max_it; current_start = max_it + 1; } return result; } auto countJoltagesP2(const std::vector>& banks) { long totalJoltage{}; for(const auto& bank : banks){ totalJoltage += calculateJoltageP2_Optimized(bank); } return totalJoltage; } auto main() -> int { auto testCase = parseBanks("test_input"); if(testCase) { //auto testResult = countJoltages(*testCase); auto testResultP2 = countJoltagesP2(*testCase); //std::println("P1 Testcase result: {}", testResult); std::println("P2 Testcase result: {}", testResultP2); } else{ std::print("{}\n", testCase.error()); } auto realPuzzle = parseBanks("puzzle_input"); if(realPuzzle) { //auto realResult = countJoltages(*realPuzzle); auto realResultP2 = countJoltagesP2(*realPuzzle); //std::println("P1 Real result: {}", realResult); std::println("P2 Real result: {}", realResultP2); } else{ std::print("{}\n", realPuzzle.error()); } return 0; }