Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using namespace std;
- int main() {
- auto start = absl::Now();
- string line = "BLAH";
- int curr = 0;
- int pos = -1;
- int next_char = 0;
- auto from_hex = [](char c) {
- if (c <='9') return c - '0';
- return c - 'A' + 10;
- };
- auto take = [&](int n) {
- long long x = 0;
- for(int i = 0; i < n; ++i) {
- x = x << 1;
- if (pos < 0) {
- pos = 3;
- curr = from_hex(line.at(next_char));
- ++next_char;
- }
- x += ((curr & 1 << pos) != 0) ? 1ll : 0ll;
- --pos;
- }
- return x;
- };
- function<long long(int*)> process;
- process = [&](int* bits) {
- take(3); // version
- auto id = take(3);
- if (bits != nullptr) {
- *bits -=6;
- }
- if (id == 4) {
- long long x = 0;
- while(true) {
- bool last = !take(1);
- x = x << 4;
- x += take(4);
- if (bits != nullptr) {
- *bits -=5;
- }
- if (last) break;
- }
- return x;
- }
- else {
- std::vector<long long> ans;
- if (!take(1)) {
- int l = take(15);
- if (bits != nullptr) {
- *bits -=16;
- *bits -=l;
- }
- while(l > 0) {
- ans.push_back(process(&l));
- }
- } else {
- int l = take(11);
- if (bits != nullptr) {
- *bits -=12;
- }
- for (int i = 0; i < l; ++i) {
- ans.push_back(process(bits));
- }
- }
- switch(id) {
- case 0: return absl::c_accumulate(ans, 0ll);
- case 1: return absl::c_accumulate(ans, 1ll, multiplies());
- case 2: return *absl::c_min_element(ans);
- case 3: return *absl::c_max_element(ans);
- case 5: return ans[0] > ans[1] ? 1ll : 0ll;
- case 6: return ans[0] < ans[1] ? 1ll : 0ll;
- case 7: return ans[0] == ans[1] ? 1ll: 0ll;
- default: throw invalid_argument("wrong id");
- }
- }
- };
- cout << process(nullptr) << endl;
- cout << absl::Now() - start << endl;
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment