diff --git a/day 023/day_23_felix.cpp b/day 023/day_23_felix.cpp new file mode 100644 index 0000000000000000000000000000000000000000..54d50ca417c4889e3076638d52a078c38b8a805c --- /dev/null +++ b/day 023/day_23_felix.cpp @@ -0,0 +1,134 @@ +/* +Usage: + g++ -o main day_X_felix.cpp (or compile however you like) + ./main < input.txt (pipe the input) + + Options: + -d : debug mode +*/ + +#include <bits/stdc++.h> +using namespace std; +bool DEBUG = false; + +// Standard definitions for many problems +#define coord pair <int, int> +#define ll long long + +array<set<int>, 676> LINKS; + +set<int> t_starters; +set<int> all_ids; + +int int_id(char c1, char c2) { + int i1 = (int)(c1) - 97; + int i2 = (int)(c2) - 97; + return i1*26 + i2; +} + +string id_to_str(int id) { + string s = ""; + s += (char)(id / 26 + 97); + s += (char)(id % 26 + 97); + return s; +} + +void read_input() { + string line; + while (getline(cin, line)) { + stringstream ss(line); + char c1, c2, dash; + ss >> c1 >> c2 >> dash; + int id1 = int_id(c1, c2); + all_ids.insert(id1); + if (c1 == 't') t_starters.insert(id1); + ss >> c1 >> c2; + int id2 = int_id(c1, c2); + all_ids.insert(id2); + if (c1 == 't') t_starters.insert(id2); + LINKS[id1].insert(id2); + LINKS[id2].insert(id1); + } + cout << "Total number of nodes: " << all_ids.size() << endl; +} + +ll part1() { + ll total = 0; + set<tuple<int, int, int>> counted; + + + for (int n1 : t_starters) for (int n2 : LINKS[n1]) for (int n3 : LINKS[n2]) { + if (counted.find({n1, n2, n3}) != counted.end()) continue; + if (!count(LINKS[n3].begin(), LINKS[n3].end(), n1)) continue; + counted.insert({n1, n2, n3}); + counted.insert({n1, n3, n2}); + counted.insert({n2, n1, n3}); + counted.insert({n2, n3, n1}); + counted.insert({n3, n1, n2}); + counted.insert({n3, n2, n1}); + total++; + } + return total; +} + +bool all_linked(int n, set<int> s) { + for (int n2 : s) if (LINKS[n].find(n2) == LINKS[n].end()) return false; + return true; +} + +// check if set s contains all elements of set t +bool contains_all(set<int> s, set<int> t) { + for (int n : t) if (s.find(n) == s.end()) return false; + return true; +} + +string set_to_str(set<int> s) { + string str = ""; + set<string> str_set; + for (int n : s) str_set.insert(id_to_str(n)); // automatically sorted + for (string s : str_set) str += s + ","; + // remove last , + str.pop_back(); + return str; +} + +set<int> part2() { + set<set<int>> sets; + for (int n : all_ids) sets.insert({n}); + int set_size = 1; + while (sets.size() > 1) { + if (DEBUG) cout << "Set size: " << set_size << " | Number of sets: " << sets.size() << endl; + set<set<int>> new_sets; + for (set<int> s : sets) for (int n : all_ids) { + if (s.find(n) != s.end()) continue; + if (all_linked(n, s)) { + set<int> new_s = s; + new_s.insert(n); + new_sets.insert(new_s); + } + } + sets = new_sets; + set_size++; + } + return *sets.begin(); +} + +int main (int argc, char* argv[]) { + for (int i = 0; i < argc; i++) if (string(argv[i]) == "-d") DEBUG = true; + + read_input(); + + if (DEBUG) { + int largest = 0; + for (int id : all_ids) if (LINKS[id].size() > largest) largest = LINKS[id].size(); + cout << "Most links: " << largest << endl; + } + + ll p1 = part1(); + cout << "Part 1: " << p1 << endl; + + set<int> p2 = part2(); + cout << "Part 2: " << set_to_str(p2) << endl; + + return 0; +} \ No newline at end of file