#include #include #include #include #include #include using namespace std; // constraints maps n to all values that need to appear after n bool checkUpdate(vector update, map>> constraints) { // holds all values that have been visited already in this update vector prev; for (auto n : update) { for (auto p : prev) { if (constraints[n].count(p)) { return false; } } prev.push_back(n); } return true; } // parse constraints, aka lines of integer tuples separated by "|" void parseConstraints(ifstream &input, map>> &constraints) { string line; while (getline(input, line) && line.size()) { stringstream line_stream; line_stream << line; int a; int b; char c; line_stream >> a; // discard "|" line_stream >> c; line_stream >> b; // add b to constraint set of a if (constraints.count(a) == 0) { set> constraint{b}; constraints.insert({a, constraint}); } else { constraints[a].insert(b); } } } // parse updates, aka lines of comma separated values void parseUpdates(ifstream &input, vector> &updates) { string line; while (getline(input, line)) { // cout << "parseUpdates got line: " << line << endl; int n; stringstream line_stream; line_stream << line; vector v; while (line_stream >> n) { v.push_back(n); char c; // discard comma line_stream >> c; } updates.push_back(v); } } // sums up the middle values of correct updates int correctUpdates(map>> constraints, vector> updates) { int sum = 0; for (auto update : updates) { if (checkUpdate(update, constraints)) { sum += update[update.size() / 2]; } } return sum; } // corrects an incorrect update by doing something akin to bubble sort // (aka swapping rule violating pairs until there are none left) void correction(vector &update, map>> constraints) { for (int i = 0; i < update.size(); i++) { for (int j = 0; j < i; j++) { if (constraints[update[i]].count(update[j])) { // swap n and p, then start over int temp = update[i]; update[i] = update[j]; update[j] = temp; correction(update, constraints); return; } } } } // sums up the middle values of incorrect updates after correcting them int incorrectUpdates(map>> constraints, vector> updates) { int sum = 0; for (auto update : updates) { if (!checkUpdate(update, constraints)) { correction(update, constraints); sum += update[update.size() / 2]; } } return sum; } int main(int argc, char *argv[]) { ifstream example("example"); ifstream input("input"); map>> constraints_example; vector> updates_example; parseConstraints(example, constraints_example); parseUpdates(example, updates_example); cout << "Update sum (example) is: " << correctUpdates(constraints_example, updates_example) << endl; cout << "Corrected update sum (example) is: " << incorrectUpdates(constraints_example, updates_example) << endl; map>> constraints_input; vector> updates_input; parseConstraints(input, constraints_input); parseUpdates(input, updates_input); cout << "Update sum (input) is: " << correctUpdates(constraints_input, updates_input) << endl; cout << "Corrected update sum (input) is: " << incorrectUpdates(constraints_input, updates_input) << endl; return 0; }