#include #include #include #include #include #include #include struct Rule{ int first; int second; Rule(int first, int second) : first(first), second(second) {} }; struct Update { std::vector pages; explicit Update(const std::vector &pages) : pages(pages) {} }; std::vector readTextFromFile(const std::string& fileName) { std::vector lines; std::ifstream file(fileName); if (!file) { // Überprüft, ob die Datei geöffnet werden konnte std::cerr << "Fehler: Datei konnte nicht geöffnet werden: " << fileName << std::endl; return lines; } std::string s; while(getline(file, s)) { lines.push_back(s); } return lines; } std::vector splitString(const std::string& input, char ch) { std::vector splittedString; size_t pos = input.find(ch); size_t initialPos = 0; while(pos != std::string::npos) { splittedString.push_back(input.substr(initialPos, pos - initialPos)); initialPos = pos + 1; pos = input.find(ch, initialPos); } splittedString.push_back(input.substr(initialPos, std::min(pos, input.size()) - initialPos)); return splittedString; } std::vector parseRules(std::vector& input) { std::vector rules; for(const auto& line : input) { if(line.find('|') != std::string::npos) { std::vector splittedLine = splitString(line, '|'); int first = std::stoi(splittedLine[0]); int second = std::stoi(splittedLine[1]); rules.emplace_back(first, second); } } return rules; } std::vector parseUpdates(std::vector& input) { std::vector updates; for(const auto& line : input) { if(line.find(',') != std::string::npos) { std::vector splittedString = splitString(line, ','); std::vector pages; for(const auto& page : splittedString) { pages.push_back(std::stoi(page)); } updates.emplace_back(pages); } } return updates; } std::vector topologicalSort(const std::vector& rules) { std::unordered_map> adjList; std::unordered_map inDegree; // Step 1: Build the graph for(const auto& rule : rules) { adjList[rule.first].insert(rule.second); inDegree[rule.second]++; if(inDegree.find(rule.first) == inDegree.end()) { inDegree[rule.first] = 0; } } // Step 2: Initialize queue with nodes having in degree 0 std::queue zeroInDegreeQueue; for(const auto& pair : inDegree) { if(pair.second == 0) { zeroInDegreeQueue.push(pair.first); } } //Step 3: Process nodes and generate topological order std::vector topologicalOrder; while(!zeroInDegreeQueue.empty()) { int current = zeroInDegreeQueue.front(); zeroInDegreeQueue.pop(); topologicalOrder.push_back(current); if(adjList.find(current) != adjList.end()) { for(const auto& neighbor : adjList[current]) { inDegree[neighbor]--; if(inDegree[neighbor] == 0) { zeroInDegreeQueue.push(neighbor); } } } } return topologicalOrder; } int indexOf(std::vector vec, int element) { for(int i=0; i< vec.size(); i++) { if(vec[i] == element) { return i; } } return -1; } //Checks whether a is before b in topological order bool isBefore(const std::vector& rules, int a, int b) { for(const Rule& rule: rules) { if(rule.second == a && rule.first == b) { return false; } } return true; } bool isAfter(const std::vector& rules, int a, int b) { for(const Rule& rule : rules) { if(rule.second == b && rule.first == a) { return false; } } return true; } bool isUpdateCorrect(const Update& update, const std::vector& rules) { std::vector topologicalOrder = topologicalSort(rules); //Check if all pages are printed after the previous one for(int i=0; i determineCorrectUpdates(std::vector& updates, std::vector& rules) { std::vector validUpdates; for(const Update& update : updates) { if(isUpdateCorrect(update, rules)) { validUpdates.push_back(update); } } return validUpdates; } std::vector determineIncorrectUpdates(std::vector& updates, std::vector& rules) { std::vector validUpdates; for(const Update& update : updates) { if(!isUpdateCorrect(update, rules)) { validUpdates.push_back(update); } } return validUpdates; } Update correctUpdate(const Update& update, std::vector& rules) { Update correctedUpdate = update; for(int i=0; i correctUpdates(std::vector& updates, std::vector& rules) { std::vector correctedUpdates; for(const Update& update : updates) { correctedUpdates.push_back(correctUpdate(update, rules)); } return correctedUpdates; } int calcMiddleSum(std::vector& updates) { int sum = 0; for(const auto& update: updates) { sum += update.pages[update.pages.size()/2]; } return sum; } int main() { std::vector input = readTextFromFile("../input.txt"); std::vector rules = parseRules(input); std::vector updates = parseUpdates(input); std::vector validUpdates = determineCorrectUpdates(updates, rules); int result = calcMiddleSum(validUpdates); std::cout << "The middle sum of the correct Updates is: " << result << std::endl; std::vector incorrectUpdates = determineIncorrectUpdates(updates, rules); std::vector correctedUpdates = correctUpdates(incorrectUpdates, rules); int result2 = calcMiddleSum(correctedUpdates); std::cout << "The middle sum of the corrected Updates is: " << result2 << std::endl; return 0; }