From e8b5a045a8d7362b1ba8260a6987dd1b8ed282bf Mon Sep 17 00:00:00 2001 From: Eric Mertens Date: Sun, 20 Nov 2022 19:44:38 -0800 Subject: [PATCH] 2020/18 --- 2020/18.cpp | 99 +++++++++++++++++++++++++++++++++++++++++++++ 2020/CMakeLists.txt | 3 ++ 2 files changed, 102 insertions(+) create mode 100644 2020/18.cpp diff --git a/2020/18.cpp b/2020/18.cpp new file mode 100644 index 0000000..d35564e --- /dev/null +++ b/2020/18.cpp @@ -0,0 +1,99 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +namespace { + +auto Eval( + std::string const& input, + std::map>> cfg +) -> std::int64_t +{ + std::vector ops; + std::vector vals; + + auto const eval1 = [&](){ + char o = ops.back(); ops.pop_back(); + std::int64_t y = vals.back(); vals.pop_back(); + std::int64_t x = vals.back(); vals.pop_back(); + vals.push_back(cfg[o].second(x,y)); + }; + + for (auto it = input.begin(); it != input.end(); it++) { + char const c = *it; + if (c == ' ') continue; + if (std::isdigit(c)) { + vals.push_back(c - '0'); + } else if ('(' == c) { + ops.push_back('('); + } else if (')' == c) { + while (ops.back() != '(') eval1(); + ops.pop_back(); + } else if (auto opit = cfg.find(c); opit != cfg.end()) { + while (!ops.empty() && cfg[ops.back()].first >= opit->second.first) eval1(); + ops.push_back(c); + } + } + + while (!ops.empty()) eval1(); + + return vals.back(); +} + +auto Part1(std::string const& line) { + return Eval(line, {{'+', {1, std::plus()}},{'*', {1, std::multiplies()}}}); +} + +auto Part2(std::string const& line) { + return Eval(line, {{'+', {2, std::plus()}},{'*', {1, std::multiplies()}}}); +} + +} // namespace + +TEST_SUITE("documented examples") { + +TEST_CASE("part 1") { + REQUIRE(Part1("1 + 2 * 3 + 4 * 5 + 6") == 71); + REQUIRE(Part1("1 + (2 * 3) + (4 * (5 + 6))") == 51); + REQUIRE(Part1("2 * 3 + (4 * 5)") == 26); + REQUIRE(Part1("5 + (8 * 3 + 9 + 3 * 4 * 3)") == 437); + REQUIRE(Part1("5 * 9 * (7 * 3 * 3 + 9 * 3 + (8 + 6 * 4))") == 12240); + REQUIRE(Part1("((2 + 4 * 9) * (6 + 9 * 8 + 6) + 6) + 2 + 4 * 2") == 13632); +} + +TEST_CASE("part 2") { + REQUIRE(Part2("1 + 2 * 3 + 4 * 5 + 6") == 231); + REQUIRE(Part2("1 + (2 * 3) + (4 * (5 + 6))") == 51); + REQUIRE(Part2("2 * 3 + (4 * 5)") == 46); + REQUIRE(Part2("5 + (8 * 3 + 9 + 3 * 4 * 3)") == 1445); + REQUIRE(Part2("5 * 9 * (7 * 3 * 3 + 9 * 3 + (8 + 6 * 4))") == 669060); + REQUIRE(Part2("((2 + 4 * 9) * (6 + 9 * 8 + 6) + 6) + 2 + 4 * 2") == 23340); +} + +} + +auto main(int argc, char** argv) -> int { + auto & in = aocpp::Startup(argc, argv); + + std::int64_t part1 = 0; + std::int64_t part2 = 0; + + std::string line; + while (std::getline(in, line)) { + part1 += Part1(line); + part2 += Part2(line); + } + + std::cout << "Part 1: " << part1 << std::endl; + std::cout << "Part 2: " << part2 << std::endl; +} diff --git a/2020/CMakeLists.txt b/2020/CMakeLists.txt index 2a3ee47..6acd5ca 100644 --- a/2020/CMakeLists.txt +++ b/2020/CMakeLists.txt @@ -7,5 +7,8 @@ target_link_libraries(2020_03 aocpp) add_executable(2020_16 16.cpp) target_link_libraries(2020_16 aocpp dlx) +add_executable(2020_18 18.cpp) +target_link_libraries(2020_18 aocpp) + add_executable(2020_21 21.cpp) target_link_libraries(2020_21 aocpp dlx) \ No newline at end of file