Advertisement
Guest User

Advent of Code 2023 Day 07 C++ Solution Both Parts

a guest
Dec 7th, 2023
124
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.56 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2. using namespace std;
  3.  
  4. vector<string> read_lines(string file_name = "input.txt") {
  5.   vector<string> res;
  6.   string line;
  7.   ifstream file(file_name);
  8.   if (file.is_open()) {
  9.     while (getline(file, line)) {
  10.       res.push_back(line);
  11.     }
  12.     file.close();
  13.   }
  14.   return res;
  15. }
  16.  
  17. vector<string> split(string s, char c = ' ') {
  18.   vector<string> res;
  19.   string cur = "";
  20.   for (char ch : s) {
  21.     if (ch == c) {
  22.       if (!cur.empty())
  23.         res.push_back(cur);
  24.       cur = "";
  25.     } else {
  26.       cur += ch;
  27.     }
  28.   }
  29.   if (!cur.empty()) {
  30.     res.push_back(cur);
  31.   }
  32.   return res;
  33. }
  34.  
  35. string rltrim(string s, char c = ' ') {
  36.   int lo = -1, hi = -1;
  37.   for (int i = 0; i < (int)s.size(); i++) {
  38.     if (s[i] != c) {
  39.       lo = i;
  40.       break;
  41.     }
  42.   }
  43.   for (int i = (int)s.size() - 1; i >= 0; i--) {
  44.     if (s[i] != c) {
  45.       hi = i;
  46.       break;
  47.     }
  48.   }
  49.   if (lo != -1 and hi != -1) {
  50.     string res = "";
  51.     for (int i = lo; i <= hi; i++)
  52.       res += s[i];
  53.     return res;
  54.   }
  55.   return "";
  56. }
  57.  
  58. int64_t silver(vector<string> lines) {
  59.   int64_t ans = 0;
  60.  
  61.   map<char, int> pw;
  62.   int ptr = 0;
  63.   for (char c : "23456789TJQKA") {
  64.     pw[c] = ptr++;
  65.   }
  66.  
  67.   auto type = [&](string s) -> int {
  68.     map<char, int64_t> cnt;
  69.     for (char c : s)
  70.       cnt[c]++;
  71.     int len = (int)cnt.size();
  72.     vector<int64_t> freq;
  73.     for (auto &[k, v] : cnt)
  74.       freq.push_back(v);
  75.     sort(freq.begin(), freq.end());
  76.     if (len == 1 and *max_element(freq.begin(), freq.end()) == 5) {
  77.       return 6;
  78.     }
  79.     if (len == 2 and *max_element(freq.begin(), freq.end()) == 4) {
  80.       return 5;
  81.     }
  82.     if (len == 2 and *max_element(freq.begin(), freq.end()) == 3) {
  83.       return 4;
  84.     }
  85.     if (len == 3 and *max_element(freq.begin(), freq.end()) == 3) {
  86.       return 3;
  87.     }
  88.     if (len == 3 and freq[2] == freq[1] and freq[2] == 2) {
  89.       return 2;
  90.     }
  91.     if (len == 4 and freq[3] == 2) {
  92.       return 1;
  93.     }
  94.     if (len == 5 and freq[4] == 1) {
  95.       return 0;
  96.     }
  97.     assert(false);
  98.     return -1;
  99.   };
  100.  
  101.   auto gr = [&](string &s, string &t) -> bool {
  102.     const int n = (int)s.size();
  103.     assert((int)t.size() == n);
  104.     vector<int> l(n), r(n);
  105.     for (int i = 0; i < n; i++) {
  106.       l[i] = pw[s[i]];
  107.       r[i] = pw[t[i]];
  108.     }
  109.     return l < r;
  110.   };
  111.  
  112.   vector<pair<string, int64_t>> opt;
  113.   for (auto &line : lines) {
  114.     vector<string> parts = split(line, ' ');
  115.     opt.emplace_back(parts[0], stoll(parts[1]));
  116.   }
  117.  
  118.   sort(opt.begin(), opt.end(), [&](auto &left, auto &right) -> bool {
  119.     string &l = left.first;
  120.     string &r = right.first;
  121.     int t_l = type(l), t_r = type(r);
  122.     if (t_l == t_r)
  123.       return gr(l, r);
  124.     return t_l < t_r;
  125.   });
  126.  
  127.   ptr = 1;
  128.   for (auto &[k, v] : opt) {
  129.     ans += v * 1LL * ptr;
  130.     ptr++;
  131.   }
  132.   return ans;
  133. }
  134.  
  135. string replace(string s, char current, char next) {
  136.   string res = "";
  137.   for (char c : s) {
  138.     if (c == current)
  139.       res += next;
  140.     else
  141.       res += c;
  142.   }
  143.   return res;
  144. }
  145.  
  146. int64_t gold(vector<string> lines) {
  147.   int64_t ans = 0;
  148.  
  149.   map<char, int> pw;
  150.   int ptr = 0;
  151.  
  152.   string all = "J23456789TQKA";
  153.   for (char c : all) {
  154.     pw[c] = ptr++;
  155.   }
  156.  
  157.   auto type = [&](string s) -> int {
  158.     map<char, int64_t> cnt;
  159.     for (char c : s)
  160.       cnt[c]++;
  161.     int len = (int)cnt.size();
  162.     vector<int64_t> freq;
  163.     for (auto &[k, v] : cnt)
  164.       freq.push_back(v);
  165.     sort(freq.begin(), freq.end());
  166.     if (len == 1 and *max_element(freq.begin(), freq.end()) == 5) {
  167.       return 6;
  168.     }
  169.     if (len == 2 and *max_element(freq.begin(), freq.end()) == 4) {
  170.       return 5;
  171.     }
  172.     if (len == 2 and *max_element(freq.begin(), freq.end()) == 3) {
  173.       return 4;
  174.     }
  175.     if (len == 3 and *max_element(freq.begin(), freq.end()) == 3) {
  176.       return 3;
  177.     }
  178.     if (len == 3 and freq[2] == freq[1] and freq[2] == 2) {
  179.       return 2;
  180.     }
  181.     if (len == 4 and freq[3] == 2) {
  182.       return 1;
  183.     }
  184.     if (len == 5 and freq[4] == 1) {
  185.       return 0;
  186.     }
  187.     assert(false);
  188.     return -1;
  189.   };
  190.  
  191.   auto gr = [&](string &s, string &t) -> bool {
  192.     const int n = (int)s.size();
  193.     assert((int)t.size() == n);
  194.     vector<int> l(n), r(n);
  195.     for (int i = 0; i < n; i++) {
  196.       l[i] = pw[s[i]];
  197.       r[i] = pw[t[i]];
  198.     }
  199.     return l < r;
  200.   };
  201.  
  202.   vector<tuple<string, string, int64_t>> opt;
  203.   for (auto &line : lines) {
  204.     vector<string> parts = split(line, ' ');
  205.     opt.emplace_back(parts[0], parts[0], stoll(parts[1]));
  206.   }
  207.  
  208.   int id = 0;
  209.   for (auto &[cur, next, value] : opt) {
  210.     string s = "";
  211.     int js = count(cur.begin(), cur.end(), 'J');
  212.     if (js > 0) {
  213.       map<char, int> cnt;
  214.       for (char c : cur)
  215.         cnt[c]++;
  216.       vector<tuple<int, int, char>> p;
  217.       for (auto &[k, v] : cnt) {
  218.         if (k != 'J')
  219.           p.emplace_back(v, pw[k], k);
  220.       }
  221.       sort(p.begin(), p.end());
  222.       if (js == 5) {
  223.         s = replace(cur, 'J', 'A');
  224.       } else {
  225.         s = replace(cur, 'J', get<2>(p.back()));
  226.       }
  227.     } else {
  228.       s = cur;
  229.     }
  230.     next = s;
  231.     id++;
  232.   }
  233.  
  234.   sort(opt.begin(), opt.end(), [&](auto &left, auto &right) -> bool {
  235.     int t_l = type(get<1>(left)), t_r = type(get<1>(right));
  236.     if (t_l == t_r)
  237.       return gr(get<0>(left), get<0>(right));
  238.     return t_l < t_r;
  239.   });
  240.  
  241.   ptr = 1;
  242.   for (auto &[k, _, v] : opt) {
  243.     ans += v * 1LL * ptr;
  244.     ptr++;
  245.   }
  246.   return ans;
  247. }
  248.  
  249. int main() {
  250.   vector<string> lines = read_lines();
  251.   cout << silver(lines) << '\n';
  252.   cout << gold(lines) << '\n';
  253.   return 0;
  254. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement