aoc25/day3/main.cpp
2025-12-04 12:54:27 +00:00

168 lines
4.2 KiB
C++

#include <iostream>
#include <fstream>
#include <iterator>
#include <string>
#include <string_view>
#include <vector>
#include <expected>
#include <print>
#include <ranges>
#include <array>
#include <map>
#include <numeric>
#include <functional>
#include <algorithm>
struct IDRange {
long leftRange;
long rightRange;
};
auto parseBanks(const std::string& filename) -> std::expected<std::vector<std::vector<int>>, std::string> {
std::ifstream inputF {filename};
if (!inputF){
return std::unexpected{"Some file open error.\n"};
}
std::vector<std::vector<int>> banks{};
std::string bankLine{};
while(std::getline(inputF,bankLine)){
banks.emplace_back(bankLine
| std::views::transform([](char c){ return c - '0';})
| std::ranges::to<std::vector<int>>());
}
inputF.close();
return std::move(banks);
}
auto calculateJoltage(const std::vector<int>& 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<std::vector<int>>& banks) {
long totalJoltage{};
for(const auto& bank : banks){
std::println("Bank: {}", bank);
totalJoltage += calculateJoltage(bank);
}
return totalJoltage;
}
auto calculateJoltageP2(const std::vector<int>& bank) -> long long{
const int TO_TAKE = 12;
std::vector<int> 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<int>& 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<std::vector<int>>& 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;
}