diff options
author | dzwdz | 2022-12-16 13:15:07 +0100 |
---|---|---|
committer | dzwdz | 2022-12-16 13:15:07 +0100 |
commit | 199c27b20a3907a176bc00320aefa267b56aeaa0 (patch) | |
tree | 7711685c21d1f2eb8b6b4c7abffad9e7c1f09f13 | |
parent | cc806faf8b45058ca50f497bfa670a9dec683fcb (diff) |
day 16 part 1 partial solution - keeping the path
-rw-r--r-- | 22.16/main.cpp | 102 |
1 files changed, 102 insertions, 0 deletions
diff --git a/22.16/main.cpp b/22.16/main.cpp new file mode 100644 index 0000000..8ccabed --- /dev/null +++ b/22.16/main.cpp @@ -0,0 +1,102 @@ +#include <deque> +#include <iostream> +#include <string> +#include <unordered_map> +#include <utility> +#include <vector> +using namespace std; + +int parseID(string s) { + return (s[0] - 'A') * ('Z' - 'A' + 1) + (s[1] - 'A'); +} + +// Fucking hell. +struct hash_pair { + template<typename T1, typename T2> + size_t operator()(const pair<T1, T2>& p) const + { + auto h1 = hash<T1>{}(p.first); + auto h2 = hash<T1>{}(p.second); + return h1 ^ (h2 << 1); + } +}; + +struct Graph { + unordered_multimap<int, int> conns; + unordered_map<int, int> rates; + + unordered_map<pair<int, int>, int, hash_pair> dist; +}; + +void findLengths(Graph &g, int base) { + deque<int> frontier; + frontier.push_back(base); + g.dist.insert({{base, base}, 0}); + while (!frontier.empty()) { + // i love c++ i love c++ i love c++ + int from = frontier.front(); + int dist = g.dist[{base, from}]; + frontier.pop_front(); + auto range = g.conns.equal_range(from); + for (auto it = range.first; it != range.second; it++) { + int to = it->second; + if (g.dist.count({base, to}) != 0) + continue; + g.dist.insert({{base, to}, dist + 1}); + frontier.push_back(to); + } + } +} + +Graph g; + +void rec(vector<int> path, vector<int> &avail, int time, int score) { + cout << score << "\t" << time << "\t"; + for (int n : path) + cout << n << ","; + cout << endl; + + int cur = path.back(); + for (int i = 0; i < avail.size(); i++) { + int n = avail[i]; + if (n == 0) continue; + avail[i] = 0; + + vector<int> path2 = path; + path2.push_back(n); + + int time2 = time + g.dist[{cur, n}] + 1; + if (30 < time2) continue; + int score2 = score + g.rates[n] * (30 - time2); + + rec(path2, avail, time2, score2); + avail[i] = n; + } +} + +int main() { + vector<int> nonzero; + for (string s; getline(cin, s); ) { + auto numStart = s.find('=') + 1; + auto numEnd = s.find(';', numStart) - numStart; + + int from = parseID(s.substr(6, 2)); + int rate = stoi(s.substr(numStart, numEnd)); + + g.rates[from] = rate; + if (rate != 0) nonzero.push_back(from); + + s = s.substr(s.find(' ', s.find("valve")) + 1); + for (int i = 0; i + 2 <= s.size(); i += 4) { + int to = parseID(s.substr(i, 2)); + g.conns.insert({from, to}); + } + } + + findLengths(g, 0); + for (int base : nonzero) + findLengths(g, base); + + vector<int> start = {0}; + rec(start, nonzero, 0, 0); +} |