#include #include #include #include #include #include #include struct Box { std::int64_t x; std::int64_t y; std::int64_t z; }; auto Part1(Box const& box) -> std::int64_t { std::array sides {box.x * box.y, box.x * box.z, box.y * box.z}; std::partial_sort(begin(sides), begin(sides)+1, end(sides)); return 2 * std::reduce(begin(sides), end(sides)) + sides[0]; } auto Part2(Box const& box) -> std::int64_t { std::array dims {box.x, box.y, box.z}; std::sort(begin(dims), end(dims)); return 2 * (dims[0] + dims[1]) + std::reduce(begin(dims), end(dims), 1, std::multiplies<>()); } TEST_SUITE("documented examples") { TEST_CASE("part 1") { REQUIRE(Part1({2,3,4}) == 58); REQUIRE(Part1({1,1,10}) == 43); } TEST_CASE("part 2") { REQUIRE(Part2({2,3,4}) == 34); REQUIRE(Part2({1,1,10}) == 14); } } auto Main(std::istream & in, std::ostream & out) -> void { std::int64_t part1 = 0; std::int64_t part2 = 0; std::string line; while (std::getline(in, line)) { namespace qi = boost::spirit::qi; using p = qi::int_parser; auto b = begin(line); // updated on successful parse auto const e = end(line); Box box; if (not qi::parse(b, e, p{} >> 'x' >> p{} >> 'x' >> p{}, box.x, box.y, box.z) || b != e) { throw std::runtime_error{"Parse error"}; } part1 += Part1(box); part2 += Part2(box); } std::cout << "Part1: " << part1 << std::endl; std::cout << "Part2: " << part2 << std::endl; }