#include #include #include #include #include #include #include #include #include #include #include namespace { enum class ABC { A, B, C }; enum class XYZ { X, Y, Z }; auto xyzScore(XYZ xyz) -> std::int64_t { switch (xyz) { case XYZ::X: return 1; case XYZ::Y: return 2; case XYZ::Z: return 3; } } auto outcome(ABC abc, XYZ xyz) -> std::int64_t { switch (abc) { case ABC::A: switch (xyz) { case XYZ::X: return 3; case XYZ::Y: return 6; case XYZ::Z: return 0; } case ABC::B: switch (xyz) { case XYZ::X: return 0; case XYZ::Y: return 3; case XYZ::Z: return 6; } case ABC::C: switch (xyz) { case XYZ::X: return 6; case XYZ::Y: return 0; case XYZ::Z: return 3; } } } auto DesiredOutcome(XYZ xyz) -> std::int64_t { switch (xyz) { case XYZ::X: return 0; case XYZ::Y: return 3; case XYZ::Z: return 6; } } auto Pick(ABC abc, XYZ xyz) -> XYZ { for (auto result : {XYZ::X, XYZ::Y, XYZ::Z}) { if (outcome(abc, result) == DesiredOutcome(xyz)) { return result; } } throw std::runtime_error{"Pick couldn't find result"}; } using Input = std::vector>; auto Parse(std::istream & in) -> Input { Input result; std::string abc, xyz; while (in >> abc >> xyz) { result.emplace_back( abc == "A" ? ABC::A : abc == "B" ? ABC::B : ABC::C, xyz == "X" ? XYZ::X : xyz == "Y" ? XYZ::Y : XYZ::Z ); } return result; } auto Part1(Input const& input) -> std::int64_t { return std::transform_reduce( input.begin(), input.end(), std::int64_t{0}, std::plus(), [](auto x) { auto [abc, xyz] = x; return outcome(abc, xyz) + xyzScore(xyz); }); } auto Part2(Input const& input) -> std::int64_t { return std::transform_reduce( input.begin(), input.end(), std::int64_t{0}, std::plus(), [](auto x) { auto [abc, xyz] = x; xyz = Pick(abc, xyz); return outcome(abc, xyz) + xyzScore(xyz); }); } } // namespace TEST_SUITE("2022-02 examples") { TEST_CASE("example") { std::istringstream in { R"(A Y B X C Z )" }; auto const input = Parse(in); CHECK(Part1(input) == 15); CHECK(Part2(input) == 12); } } auto Main(std::istream & in) -> void { auto const input {Parse(in)} ; std::cout << "Part 1: " << Part1(input) << std::endl; std::cout << "Part 2: " << Part2(input) << std::endl; }