#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); } return result; } auto Part1(std::vector entries) { std::bitset<2020> numbers; std::sort(entries.begin(), entries.end()); 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 entries) { std::bitset<2020> numbers; std::sort(entries.begin(), entries.end()); 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(int argc, char** argv) -> int { auto entries = Parse(aocpp::Startup(argc, argv)); std::cout << "Part 1: " << Part1(entries) << std::endl; std::cout << "Part 2: " << Part2(entries) << std::endl; }