aocpp/2015/02.cpp

72 lines
1.6 KiB
C++
Raw Normal View History

2024-06-10 11:08:30 -07:00
#include <aocpp/Startup.hpp>
#include <boost/spirit/include/qi.hpp>
#include <doctest.h>
#include <algorithm>
#include <array>
#include <functional>
#include <numeric>
struct Box
{
std::int64_t x;
std::int64_t y;
std::int64_t z;
};
auto Part1(Box const& box) -> std::int64_t
{
std::array<std::int64_t, 3> 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<std::int64_t, 3> 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<std::int64_t>;
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;
}