diff --git a/dat/24/ex/03b.txt b/dat/24/ex/03b.txt new file mode 100644 index 0000000..30032cb --- /dev/null +++ b/dat/24/ex/03b.txt @@ -0,0 +1 @@ +xmul(2,4)&mul[3,7]!^don't()_mul(5,5)+mul(32,64](mul(11,8)undo()?mul(8,5)) diff --git a/sol/24/day03.cpp b/sol/24/day03.cpp index 7978a7e..720f85e 100644 --- a/sol/24/day03.cpp +++ b/sol/24/day03.cpp @@ -111,7 +111,7 @@ public: public: inline static auto is_identifier(std::string_view const& str) -> bool { - return ctre::match<"^[a-z]+$">(str); + return ctre::match<"^[a-z']+$">(str); } inline static auto is_numeric_literal(std::string_view const& str) -> bool { @@ -163,15 +163,15 @@ private: return token(str, type, token_type_category(type), m_line, col); } - if (peek() == 'm') { + // mul, do, don't identifier + if (peek() == 'm' || peek() == 'd') { auto const is_valid_identifier_char = [](auto const c) { - return c >= 'a' && c <= 'z'; + return (c >= 'a' && c <= 'z') || c == '\''; }; while (is_valid_identifier_char(peek())) str += peek_consume(); auto const check_type = [](auto const str) { if (!token::is_identifier(str)) return token_type::invalid; - if (str == "mul") return token_type::identifier; - return token_type::invalid; + return token_type::identifier; }; auto const& type = check_type(str); return token(str, type, token_type_category(type), m_line, col); @@ -236,7 +236,7 @@ private: return static_cast(m_strm.get()); } auto has_next() const -> bool { - return !m_strm.eof(); + return !m_strm.eof() && m_strm.good(); } private: @@ -279,6 +279,7 @@ public: private: auto call_expression_str() const -> std::string { + if (m_nodes.size() == 0) return ""; using namespace std::string_literals; std::string str{", ["}; for (std::size_t i = 0; i < m_nodes.size(); ++i) { @@ -392,14 +393,50 @@ auto aoc::entry([[maybe_unused]]std::vector const& args) -> vo auto const tokens = lexer.tokenize(); auto const nodes = parser.parse(tokens); - auto op = nodes | std::views::transform([](auto const& node) { + // for (auto const& token : tokens) { + // fmt::print("{}\n", token.str()); + // } + // + // for (auto const& node : nodes) { + // fmt::print("{}\n", node.str()); + // } + + auto opa = nodes | std::views::filter([](auto const& node) { + return node.value() == "mul"; + }) | std::views::transform([](auto const& node) { auto const a = std::stoi(node.nodes()[0].value()); auto const b = std::stoi(node.nodes()[1].value()); return a * b; }); - auto const sum = std::accumulate(std::begin(op), std::end(op), 0); + auto const sum = std::accumulate(std::begin(opa), std::end(opa), 0); fmt::print("Part A: {}\n", sum); + + std::vector program{}; + bool is_do = true; + for (auto const& node : nodes) { + if (node.value() == "do") { + is_do = true; + continue; + } + if (node.value() == "don't") { + is_do = false; + continue; + } + if (is_do) program.push_back(node); + } + + auto opb = program | std::views::filter([](auto const& node) { + return node.value() == "mul"; + }) | std::views::transform([](auto const& node) { + auto const a = std::stoi(node.nodes()[0].value()); + auto const b = std::stoi(node.nodes()[1].value()); + return a * b; + }); + + auto const sumb = std::accumulate(std::begin(opb), std::end(opb), 0); + + fmt::print("Part B: {}\n", sumb); }