#include #include #include #include #include #include #include #include #include #include #include #include #include namespace { auto Parse(std::istream & in) -> std::vector { std::vector result; std::string line; while (std::getline(in, line)) { result.emplace_back(std::move(line)); } return result; } auto Priority(char const c) -> std::int64_t { return c < 'a' ? c-'A'+27 : c-'a'+1; } auto Intersect( std::string::const_iterator start1, std::string::const_iterator end1, std::string::const_iterator start2, std::string::const_iterator end2 ) -> std::string { std::string common; std::set_intersection( start1, end1, start2, end2, std::back_inserter(common)); return common; } auto Part1(std::vector & input) -> std::int64_t { return std::transform_reduce( input.begin(), input.end(), std::int64_t{0}, std::plus(), // sum [](auto & line) { auto const mid = line.begin() + line.size() / 2; std::sort(line.begin(), mid); std::sort(mid, line.end()); auto const common = Intersect(line.begin(), mid, mid, line.end()); return Priority(common.at(0)); }); } auto Part2(std::vector & input) -> std::int64_t { for (auto & line : input) { std::sort(line.begin(), line.end()); } auto const range = boost::irange(0, input.size(), 3); return std::transform_reduce( range.begin(), range.end(), std::int64_t{0}, std::plus(), // sum [&input](auto const i) { auto const input01 = Intersect( input[i ].begin(), input[i ].end(), input[i+1].begin(), input[i+1].end()); auto const input012 = Intersect( input01 .begin(), input01 .end(), input[i+2].begin(), input[i+2].end()); return Priority(input012.at(0)); }); } } // namespace TEST_SUITE("2022-03 examples") { TEST_CASE("example") { std::istringstream in { "vJrwpWtwJgWrhcsFMMfFFhFp\n" "jqHRNqRjqzjGDLGLrsFMfFZSrLrFZsSL\n" "PmmdzqPrVvPwwTWBwg\n" "wMqvLMZHhHMvwLHjbvcjnnSBnvTQFn\n" "ttgJtRGJQctTZtZT\n" "CrZsJsPPZsGzwwsLwLmpwMDw\n"}; auto input = Parse(in); CHECK(Part1(input) == 157); CHECK(Part2(input) == 70); } } auto Main(std::istream & in, std::ostream & out) -> void { auto input {Parse(in)}; out << "Part 1: " << Part1(input) << std::endl; out << "Part 2: " << Part2(input) << std::endl; }