#include #include #include #include "aoc.hpp" #include "aoc/utils.hpp" #include "fmt/format.h" using namespace aoc::types; using namespace std::string_view_literals; namespace rbr { enum class op { add, mul, }; class expr { public: expr(u64 eres, std::vector const& operands) : m_eres(eres), m_operands(operands) { find_res(); } auto find_res() -> bool { auto const max = std::pow(2, m_operands.size()); for (u32 t = 0; t < max; ++t) { m_ops = t; m_res = 0; compute(); if (m_res == m_eres) break; } return m_res == m_eres; } auto compute() -> void { for (usize i = 0; i < m_operands.size(); ++i) { if (i == 0) { m_res = m_operands[0]; continue; } auto const a = m_res; auto const b = m_operands[i]; auto const am = op((m_ops >> (i - 1)) & 0x01); if (am == op::add) m_res = a + b; else m_res = a * b; } } auto res() const -> u64 { return m_eres; } auto eres() const -> u64 { return m_eres; } auto operands() const -> std::vector const& { return m_operands; } auto ops() const -> u32 const& { return m_ops; } auto valid() const -> bool { return m_res == m_eres; }; auto str() const -> std::string { using namespace std::string_literals; std::string str{"expr {"}; str += " expect: "s + std::to_string(m_eres) + ","; str += " expr: "s; str += std::to_string(m_res) + " = "; for (usize i = 0; i < m_operands.size(); ++i) { auto const& operand = m_operands[i + 0]; str += std::to_string(operand); if (i == m_operands.size() - 1) break; str += ((m_ops >> i) & 0x01) == 0x01 ? "+" : "*"; } str += " }"; return str; } private: u64 m_eres; std::vector m_operands; u64 m_res{0x00}; u32 m_ops{0x00}; }; auto str_to_op(std::string const& str) -> expr { auto const splitc = str | std::views::split(": "sv) | std::views::transform([](auto const& str){ return std::string(std::begin(str), std::end(str)); }) | std::views::filter([](auto const& str) { return !str.empty(); }) | std::ranges::to(); u64 const a = std::stoull(splitc[0]); auto const b = splitc[1] | std::views::split(" "sv) | std::views::transform([](auto const& str){ return std::string(std::begin(str), std::end(str)); }) | std::views::filter([](auto const& str) { return !str.empty(); }) | std::views::transform([](auto const& str) { return std::stoull(str); }) | std::ranges::to(); return {a, b}; } } auto aoc24::day07([[maybe_unused]]std::span const& args) -> std::expected { // auto res = aoc::read_text("./dat/24/ex/07.txt"); auto res = aoc::read_text("./dat/24/re/07.txt"); if (!res) return std::unexpected(res.error()); auto const txt = *res; auto exprs = txt | std::views::split("\n"sv) | std::views::transform([](auto const& str){ return std::string(std::begin(str), std::end(str)); }) | std::views::filter([](auto const& str) { return !str.empty(); }) | std::views::transform(rbr::str_to_op); auto const valids = exprs | std::views::filter([](auto const expr) { return expr.valid(); }) | std::views::transform([](auto const& e) { return f64(e.eres()); }) | std::ranges::to(); auto const sum = std::accumulate(std::begin(valids), std::end(valids), 0.0); fmt::print("{}\n", sum); // auto const validsex = exprs | std::views::filter([](auto const expr) { return !expr.valid(); }) // | std::ranges::to(); // // for (auto const& exp : validsex) { // fmt::print("{}\n", exp.str()); // } return {}; }