Finished day 5
This commit is contained in:
parent
aea9dbe4c5
commit
aae7ebead9
3 changed files with 1512 additions and 0 deletions
28
05/example
Normal file
28
05/example
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
47|53
|
||||||
|
97|13
|
||||||
|
97|61
|
||||||
|
97|47
|
||||||
|
75|29
|
||||||
|
61|13
|
||||||
|
75|53
|
||||||
|
29|13
|
||||||
|
97|29
|
||||||
|
53|29
|
||||||
|
61|53
|
||||||
|
97|53
|
||||||
|
61|29
|
||||||
|
47|13
|
||||||
|
75|47
|
||||||
|
97|75
|
||||||
|
47|61
|
||||||
|
75|61
|
||||||
|
47|29
|
||||||
|
75|13
|
||||||
|
53|13
|
||||||
|
|
||||||
|
75,47,61,53,29
|
||||||
|
97,61,53,29,13
|
||||||
|
75,29,13
|
||||||
|
75,97,47,61,53
|
||||||
|
61,13,29
|
||||||
|
97,13,75,29,47
|
133
05/main.cc
Normal file
133
05/main.cc
Normal file
|
@ -0,0 +1,133 @@
|
||||||
|
#include <fstream>
|
||||||
|
#include <iostream>
|
||||||
|
#include <sstream>
|
||||||
|
#include <vector>
|
||||||
|
#include <map>
|
||||||
|
#include <set>
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
// constraints maps n to all values that need to appear after n
|
||||||
|
bool checkUpdate(vector<int> update, map<int, set<int, greater<int>>> constraints) {
|
||||||
|
// holds all values that have been visited already in this update
|
||||||
|
vector<int> 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<int, set<int, greater<int>>> &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<int, greater<int>> constraint{b};
|
||||||
|
constraints.insert({a, constraint});
|
||||||
|
} else {
|
||||||
|
constraints[a].insert(b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// parse updates, aka lines of comma separated values
|
||||||
|
void parseUpdates(ifstream &input, vector<vector<int>> &updates) {
|
||||||
|
string line;
|
||||||
|
while (getline(input, line)) {
|
||||||
|
// cout << "parseUpdates got line: " << line << endl;
|
||||||
|
int n;
|
||||||
|
stringstream line_stream;
|
||||||
|
line_stream << line;
|
||||||
|
vector<int> 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<int, set<int, greater<int>>> constraints, vector<vector<int>> 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<int> &update, map<int, set<int, greater<int>>> 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<int, set<int, greater<int>>> constraints, vector<vector<int>> 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<int, set<int, greater<int>>> constraints_example;
|
||||||
|
vector<vector<int>> 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<int, set<int, greater<int>>> constraints_input;
|
||||||
|
vector<vector<int>> 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;
|
||||||
|
}
|
Loading…
Reference in a new issue