ErnestGalbrun

aoc 16

Dec 16th, 2021 (edited)
81
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.85 KB | None | 0 0
  1. using namespace std;
  2.  
  3. int main() {
  4.     auto start = absl::Now();
  5.     string line = "A20D5080210CE4BB9BAFB001BD14A4574C014C004AE46A9B2E27297EECF0C013F00564776D7E3A825CAB8CD47B6C537DB99CD746674C1000D29BBC5AC80442966FB004C401F8771B61D8803D0B22E4682010EE7E59ACE5BC086003E3270AE4024E15C8010073B2FAD98E004333F9957BCB602E7024C01197AD452C01295CE2DC9934928B005DD258A6637F534CB3D89A944230043801A596B234B7E58509E88798029600BCF5B3BA114F5B3BA10C9E77BAF20FA4016FCDD13340118B929DD4FD54E60327C00BEB7002080AA850031400D002369400B10034400F30021400F20157D804AD400FE00034E000A6D001EB2004E5C00B9AE3AC3C300470029091ACADBFA048D656DFD126792187008635CD736B3231A51BA5EBDF42D4D299804F26B33C872E213C840022EC9C21FFB34EDE7C559C8964B43F8AD77570200FC66697AFEB6C757AC0179AB641E6AD9022006065CEA714A4D24C0179F8E795D3078026200FC118EB1B40010A8D11EA27100990200C45A83F12C401A8611D60A0803B1723542889537EFB24D6E0844004248B1980292D608D00423F49F9908049798B4452C0131006230C14868200FC668B50650043196A7F95569CF6B663341535DCFE919C464400A96DCE1C6B96D5EEFE60096006A400087C1E8610A4401887D1863AC99F9802DC00D34B5BCD72D6F36CB6E7D95EBC600013A88010A8271B6281803B12E124633006A2AC3A8AC600BCD07C9851008712DEAE83A802929DC51EE5EF5AE61BCD0648028596129C3B98129E5A9A329ADD62CCE0164DDF2F9343135CCE2137094A620E53FACF37299F0007392A0B2A7F0BA5F61B3349F3DFAEDE8C01797BD3F8BC48740140004322246A8A2200CC678651AA46F09AEB80191940029A9A9546E79764F7C9D608EA0174B63F815922999A84CE7F95C954D7FD9E0890047D2DC13B0042488259F4C0159922B0046565833828A00ACCD63D189D4983E800AFC955F211C700";
  6.     int curr = 0;
  7.     int pos = -1;
  8.     int next_char = 0;
  9.  
  10.     auto from_hex = [](char c) {
  11.         if (c <='9') return c - '0';
  12.         return c - 'A' + 10;
  13.     };
  14.  
  15.     auto take = [&](int n) {
  16.         long long x = 0;
  17.         for(int i = 0; i < n; ++i) {
  18.             x = x << 1;
  19.             if (pos < 0) {
  20.                 pos = 3;
  21.                 curr = from_hex(line.at(next_char));
  22.                 ++next_char;
  23.             }
  24.             x += ((curr & 1 << pos) != 0) ? 1 : 0;
  25.             curr &= ~(1 << pos);
  26.             --pos;
  27.         }
  28.         return x;
  29.     };
  30.  
  31.     function<long long(int*)> process;
  32.     process = [&](int* bits) {
  33.         take(3); // version
  34.         auto id = take(3);
  35.         if (bits != nullptr) {
  36.             *bits -=6;
  37.         }
  38.         if (id == 4) {
  39.             long long x = 0;
  40.             while(true) {
  41.                 bool last = !take(1);
  42.                 x = x << 4;
  43.                 x += take(4);
  44.                 if (bits != nullptr) {
  45.                     *bits -=5;
  46.                 }
  47.                 if (last) break;
  48.             }
  49.             return x;
  50.         }
  51.         else {
  52.             std::vector<long long> ans;
  53.             if (!take(1)) {
  54.                 int l = take(15);
  55.                 if (bits != nullptr) {
  56.                     *bits -=16;
  57.                     *bits -=l;
  58.                 }
  59.                 while(l > 0) {
  60.                     ans.push_back(process(&l));
  61.                 }
  62.             } else {
  63.                 int l = take(11);
  64.                 if (bits != nullptr) {
  65.                     *bits -=12;
  66.                 }
  67.                 for (int i = 0; i < l; ++i) {
  68.                     ans.push_back(process(bits));
  69.                 }
  70.             }
  71.             switch(id) {
  72.                 case 0: return absl::c_accumulate(ans, 0ll);
  73.                 case 1: return absl::c_accumulate(ans, 1ll, multiplies());
  74.                 case 2: return *absl::c_min_element(ans);
  75.                 case 3: return *absl::c_max_element(ans);
  76.                 case 5: return ans[0] > ans[1] ? 1ll : 0ll;
  77.                 case 6: return ans[0] < ans[1] ? 1ll : 0ll;
  78.                 case 7: return ans[0] == ans[1] ? 1ll: 0ll;
  79.                 default: throw invalid_argument("wrong id");
  80.             }
  81.         }
  82.     };
  83.     cout << process(nullptr) << endl;
  84.     cout << absl::Now() - start << endl;
  85.  
  86.     return 0;
  87. }
Advertisement
Add Comment
Please, Sign In to add comment