diff --git a/Aufgabe 5/main.cpp b/Aufgabe 5/main.cpp new file mode 100644 index 0000000..3dd05eb --- /dev/null +++ b/Aufgabe 5/main.cpp @@ -0,0 +1,195 @@ +#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; +} + +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 correctUpdates = determineCorrectUpdates(updates, rules); + int result = calcMiddleSum(correctUpdates); + std::cout << "The middle sum of the correct Updates is: " << result << std::endl; + return 0; +}