164 lines
5.5 KiB
C++
164 lines
5.5 KiB
C++
#include <vector>
|
|
#include <ranges>
|
|
#include <numeric>
|
|
|
|
#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<u64> 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<u64> 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<u64> 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<u64> 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<std::vector>();
|
|
|
|
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<std::vector>();
|
|
return {a, b};
|
|
}
|
|
}
|
|
|
|
auto aoc24::day07([[maybe_unused]]std::span<char const*> const& args) -> std::expected<void, aoc::error> {
|
|
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<std::vector>();
|
|
//
|
|
// 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<std::vector>();
|
|
//
|
|
// for (auto const& exp : exprs) {
|
|
// fmt::print("{}\n", exp.str());
|
|
// }
|
|
return {};
|
|
}
|