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