#include #include #include #include #include #include #include #include #include namespace { auto Parse(std::istream & in) -> std::vector { std::vector result; std::int64_t x; while (in >> x) { result.push_back(x); } std::sort(result.begin(), result.end()); return result; } auto Part1(std::vector const& entries) { std::bitset<2020> numbers; for (auto const i : entries) { if (i >= 2020) { break; } numbers.set(i); } for (auto const i : entries) { if (numbers.test(2020 - i)) { return (2020 - i) * i; } } throw std::runtime_error{"no part 1 solution"}; } auto Part2(std::vector const& entries) { std::bitset<2020> numbers; for (auto const i : entries) { if (i >= 2020) { break; } if (i < 2020) { numbers.set(i); } } for (auto it1 = entries.begin(); it1 != entries.end(); it1++) { for (auto it2 = std::next(it1); it2 != entries.end(); it2++) { auto target = 2020 - (*it1) - (*it2); if (target < 0) break; if (target < 2020 && numbers.test(target)) { return target * *it1 * *it2;} } } throw std::runtime_error{"no part 2 solution"}; } } TEST_SUITE("documented examples") { std::istringstream in { "1721\n" "979\n" "366\n" "299\n" "675\n" "1456\n"}; auto entries = Parse(in); TEST_CASE("part 1") { REQUIRE(Part1(entries) == 514579); } TEST_CASE("part 2") { REQUIRE(Part2(entries) == 241861950); } } auto Main(std::istream & in) -> void { auto const entries {Parse(in)}; std::cout << "Part 1: " << Part1(entries) << std::endl; std::cout << "Part 2: " << Part2(entries) << std::endl; }