aoc24: day16 create graph

This commit is contained in:
2024-12-16 21:17:17 +01:00
parent 9c840a7c8f
commit 5c7da45fe1
3 changed files with 152 additions and 54 deletions

View File

@@ -13,8 +13,18 @@ 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)
@@ -23,8 +33,8 @@ public:
}
auto find_res() -> bool {
auto const max = std::pow(2, m_operands.size());
for (u32 t = 0; t < max; ++t) {
auto const max = u64(std::pow(3, m_operands.size()));
for (u64 t = 0; t < max; ++t) {
m_ops = t;
m_res = 0;
compute();
@@ -33,25 +43,36 @@ public:
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];
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 = m_operands[i];
auto const am = op((m_ops >> (i - 1)) & 0x01);
auto const b = ops[i];
auto const am = op((m_ops >> (i * 2)) & 0x03);
if (am == op::add)
m_res = a + b;
else
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 -> u32 const& { return m_ops; }
auto ops() const -> u64 const& { return m_ops; }
auto valid() const -> bool { return m_res == m_eres; };
auto str() const -> std::string {
@@ -64,7 +85,13 @@ public:
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 ? "+" : "*";
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;
@@ -74,7 +101,7 @@ private:
u64 m_eres;
std::vector<u64> m_operands;
u64 m_res{0x00};
u32 m_ops{0x00};
u64 m_ops{0x00};
};
auto str_to_op(std::string const& str) -> expr {
@@ -98,30 +125,38 @@ auto str_to_op(std::string const& str) -> expr {
}
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");
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);
u64 test = 0b1100'1100;
fmt::print("{:b}\n", test);
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>();
test = (test & ~0b1100u) >> 2;
fmt::print("{:b}\n", test);
auto const sum = std::accumulate(std::begin(valids), std::end(valids), 0.0);
// fmt::print("{}\n", rbr::op_to_str(rbr::op(test >> 2)));
fmt::print("{}\n", sum);
// 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 : validsex) {
// for (auto const& exp : exprs) {
// fmt::print("{}\n", exp.str());
// }
return {};