#include #include #include #include using namespace std; struct Packet : pair> { unsigned &val = first; vector &vec = second; bool is_vec = false; ~Packet() { for (auto x : vec) delete x; } }; struct Input : vector { ~Input() { for (auto x : *this) delete x; } }; Packet *parse_packet(string::iterator it, string::iterator end) { Packet *p = new Packet(); if (it >= end) return p; if (*it == '[') { p->is_vec = true; auto start = it + 1; unsigned depth = 0; for (it++; it < end; it++) { if (!depth && start != it && (*it == ']' || *it == ',')) { p->vec.push_back(parse_packet(start, it)); start = it + 1; } if (*it == '[') depth++; if (*it == ']') if (!depth--) break; } } else { p->val = stoi(string(it, end)); } return p; } Input parse() { Input data; for (string line; getline(cin, line);) { if (line.empty()) continue; data.push_back(parse_packet(line.begin(), line.end())); } return data; } int operator-(const Packet &l, const Packet &r) { Packet n; const Packet *pl = &l; const Packet *pr = &r; if (pl->is_vec != pr->is_vec) { Packet *nv = new Packet(); n.is_vec = true; n.vec.push_back(nv); if (!pl->is_vec) { nv->val = pl->val; pl = &n; } if (!pr->is_vec) { nv->val = pr->val; pr = &n; } } if (pl->is_vec && pr->is_vec) { unsigned len = min(pl->vec.size(), pr->vec.size()); int diff = 0; for (unsigned i = 0; i < len; i++) { Packet *il = pl->vec[i]; Packet *ir = pr->vec[i]; diff = *il - *ir; if (diff) break; } if (!diff) diff = pl->vec.size() - pr->vec.size(); return diff; } return pl->val - pr->val; } void print_packet(Packet *p) { if (p->is_vec) { clog << '['; for (unsigned i = 0; i < p->vec.size(); i++) { if (i) clog << ','; print_packet(p->vec[i]); } clog << ']'; } else { clog << p->val; } } unsigned p1(const Input &input) { unsigned count = 0; for (unsigned i = 0; i + 1 < input.size(); i += 2) { if (*input[i] - *input[i + 1] < 0) count += (i / 2) + 1; } return count; } unsigned p2(const Input &input) { vector sorted = input; string div1_s = "[[2]]"; string div2_s = "[[6]]"; Packet *div1 = parse_packet(div1_s.begin(), div1_s.end()); Packet *div2 = parse_packet(div2_s.begin(), div2_s.end()); sorted.push_back(div1); sorted.push_back(div2); sort(sorted.begin(), sorted.end(), [](Packet *l, Packet *r){ return *l - *r < 0; }); //for (auto i : sorted) { //print_packet(i); //clog << endl; //} unsigned div1_i = 1 + find(sorted.begin(), sorted.end(), div1) - sorted.begin(); unsigned div2_i = 1 + find(sorted.begin(), sorted.end(), div2) - sorted.begin(); delete div1; delete div2; return div1_i * div2_i; } int main() { auto input = parse(); cout << p1(input) << endl; cout << p2(input) << endl; }