Finished day 5

This commit is contained in:
Leon Vatthauer 2024-12-05 13:12:43 +01:00
parent aea9dbe4c5
commit aae7ebead9
Signed by: leonv
SSH key fingerprint: SHA256:G4+ddwoZmhLPRB1agvXzZMXIzkVJ36dUYZXf5NxT+u8
3 changed files with 1512 additions and 0 deletions

28
05/example Normal file
View 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

1351
05/input Normal file

File diff suppressed because it is too large Load diff

133
05/main.cc Normal file
View 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;
}