#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, cat, }; auto op_to_str(rbr::op value) -> char const* { switch(value) { case op::add: return "+"; case op::mul: return "*"; case op::cat: return "||"; default: return "none"; } } 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 = u64(std::pow(3, m_operands.size())); for (u64 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 { std::vector ops{}; for (usize i = 0; i < m_operands.size() - 1; ++i) { auto const mode = op((m_ops >> (i * 2)) & 0x03); if (mode == op::mul) { ops.push_back(std::stoull(fmt::format("{}{}", m_operands[i + 0], m_operands[i + 1]))); ++i; m_ops = m_ops | ((m_ops & ~u64(mode)) >> 2); continue; } ops.push_back(m_operands[i]); } for (usize i = 0; i < ops.size(); ++i) { if (i == 0) { m_res = ops[0]; continue; } auto const a = m_res; auto const b = ops[i]; auto const am = op((m_ops >> (i * 2)) & 0x03); if (am == op::add) m_res = a + b; else if (am == op::mul) 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 -> u64 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; auto const mode = op((m_ops >> (i * 2)) & 0x03); if (mode == op::add) str += " + "; else if (mode == op::mul) str += " * "; else str += " || "; } str += " }"; return str; } private: u64 m_eres; std::vector m_operands; u64 m_res{0x00}; u64 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; u64 test = 0b1100'1100; fmt::print("{:b}\n", test); test = (test & ~0b1100u) >> 2; fmt::print("{:b}\n", test); // fmt::print("{}\n", rbr::op_to_str(rbr::op(test >> 2))); // 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 : exprs) { // fmt::print("{}\n", exp.str()); // } return {}; }