#include #include #include #include #include #include class print_job { std::vector page_order; std::set pages; public: print_job(std::stringstream& ss); bool before(int before, int after) const; bool contains(int page) const; int middle() const; template void sort(Compare comp); }; print_job::print_job(std::stringstream& ss) { int page; while (ss >> page) { page_order.emplace_back(page); pages.emplace(page); ss.ignore(1, ','); } } bool print_job::before(int before, int after) const { return std::distance(page_order.begin(), std::find(page_order.begin(), page_order.end(), before)) < std::distance(page_order.begin(), std::find(page_order.begin(), page_order.end(), after)); } bool print_job::contains(int page) const { return pages.contains(page); } int print_job::middle() const { return page_order[page_order.size() / 2]; } template void print_job::sort(Compare comp) { std::sort(page_order.begin(), page_order.end(), comp); } class rule { public: int before; int after; rule(std::stringstream& ss); bool valid(const print_job& job) const; }; rule::rule(std::stringstream& ss) { ss >> before; ss.ignore(1, '|'); ss >> after; } bool rule::valid(const print_job& job) const { return !job.contains(before) || !job.contains(after) || job.before(before, after); } class rule_set { std::vector rules; public: rule_set(std::istream& is); bool valid(const print_job& job) const; bool before(int a, int b) const; }; rule_set::rule_set(std::istream& is) { std::string line; while (std::getline(is, line)) { if (line == "") { return; } std::stringstream ss(line); rules.emplace_back(ss); } } bool rule_set::valid(const print_job& job) const { return std::ranges::all_of(rules, [&](auto rule) { return rule.valid(job); }); } bool rule_set::before(int a, int b) const { for (const rule& r : rules) { if (r.before == a && r.after == b) { return true; } } return false; } int main() { rule_set rules(std::cin); std::string line; int sum = 0; while (std::getline(std::cin, line)) { std::stringstream ss(line); print_job job(ss); if (!rules.valid(job)) { job.sort([&](int a, int b) { return rules.before(a, b); }); sum += job.middle(); } } std::cout << sum << std::endl; return EXIT_SUCCESS; }