diff --git a/dat/24/ex/17.txt b/dat/24/ex/17a.txt similarity index 100% rename from dat/24/ex/17.txt rename to dat/24/ex/17a.txt diff --git a/dat/24/ex/17b.txt b/dat/24/ex/17b.txt new file mode 100644 index 0000000..f69bbc0 --- /dev/null +++ b/dat/24/ex/17b.txt @@ -0,0 +1,5 @@ +Register A: 117440 +Register B: 0 +Register C: 0 + +Program: 0,3,5,4,3,0 diff --git a/sol/24/CMakeLists.txt b/sol/24/CMakeLists.txt index 41ccd9c..787c216 100644 --- a/sol/24/CMakeLists.txt +++ b/sol/24/CMakeLists.txt @@ -15,7 +15,7 @@ set(SOURCES "day10.cpp" # "day11.cpp" "day14.cpp" - "day16.cpp" + # "day16.cpp" "day17.cpp" ) add_library(aoc24 STATIC ${HEADERS} ${SOURCES}) diff --git a/sol/24/aoc.cpp b/sol/24/aoc.cpp index 84ef906..ec4fc9b 100644 --- a/sol/24/aoc.cpp +++ b/sol/24/aoc.cpp @@ -30,7 +30,7 @@ auto entry([[maybe_unused]]std::span const& args) -> std::expected< case 10: return day10(args); // case 11: return day11(args); case 14: return day14(args); - case 16: return day16(args); + // case 16: return day16(args); case 17: return day17(args); default: return aoc::make_error(fmt::format("day {}", day), std::errc::not_supported); diff --git a/sol/24/day16.cpp b/sol/24/day16.cpp index 813ab73..70360af 100644 --- a/sol/24/day16.cpp +++ b/sol/24/day16.cpp @@ -2,6 +2,8 @@ #include #include #include +#include +#include #include "aoc.hpp" #include "aoc/utils.hpp" @@ -18,7 +20,7 @@ struct edge { auto str() const -> std::string { if (b == 0) return "nil"; - return fmt::format("{},{}", (b >> 32), b & 0xFFFFFFFF); + return fmt::format("{}.{}", (b >> 32), b & 0xFFFFFFFF); } }; @@ -31,20 +33,21 @@ struct node { auto str() const -> std::string { std::string str{"node {"}; - str += " id: " + fmt::format("{},{}", (id >> 32) & 0xFFFFFFFF, id & 0xFFFFFFFF) + ","; + str += " id: " + fmt::format("{}.{}", (id >> 32) & 0xFFFFFFFF, id & 0xFFFFFFFF); if (n.b != 0) - str += " n -> " + n.str() + ","; + str += ", n → " + n.str(); if (s.b != 0) - str += " s -> " + s.str() + ","; + str += ", s → " + s.str(); if (e.b != 0) - str += " e -> " + e.str() + ","; + str += ", e → " + e.str(); if (w.b != 0) - str += " w -> " + w.str(); + str += ", w → " + w.str(); str += " }"; return str; } }; + class graph { public: graph(std::string const& maze_str) : m_start(0), m_exit(0) { @@ -55,6 +58,8 @@ public: } } + auto vertices() const -> std::vector const& { return m_nodes; } + private: auto build(std::string const& maze) -> void { auto const lines = maze | aoc::split("\n"sv) @@ -83,7 +88,7 @@ private: if (n_e != '#') { n.n = { .a = n.id, - .b = u64((u64(i - 2) << 32) | (j + 1)) + .b = u64((u64(i) << 32) | (j + 1)) }; m_edges.emplace_back(n.n); } @@ -97,7 +102,7 @@ private: if (e_e != '#') { n.e = { .a = n.id, - .b = u64((u64(i + 1) << 32) | (j - 2)) + .b = u64((u64(i + 1) << 32) | (j)) }; m_edges.emplace_back(n.e); } @@ -122,6 +127,30 @@ private: u64 m_rows{}; u64 m_cols{}; }; + +// auto dfs() -> void {} +// auto bfs() -> void {} + +auto dijkstra(graph const& g, u64 source) -> void { + std::map dist{}; + std::map prev{}; + for (auto const& v : g.vertices()) { + dist.insert({v.id, aoc::lim::max()}); + prev.insert({v.id, -1}); + } + dist[source] = 0; + std::queue q{}; + q.push(g.vertices()[0]); + + while (!q.empty()) { + node u = q.pop(); + + if (u.n.b != 0) { + i64 alt = dist[u.id] == aoc::lim::max() ? 1 : dist[u.id] + 1; + } + } +} + } auto aoc24::day16([[maybe_unused]]std::span const& args) -> std::expected { diff --git a/sol/24/day17.cpp b/sol/24/day17.cpp index 0065409..af909b0 100644 --- a/sol/24/day17.cpp +++ b/sol/24/day17.cpp @@ -2,6 +2,7 @@ #include #include #include +#include #include "aoc.hpp" #include "aoc/utils.hpp" @@ -14,15 +15,15 @@ using namespace std::string_view_literals; namespace uec { enum class opcode : u16 { - adv, - bxl, - bst, - jnz, - bxc, - out, - bdv, - cdv, - nop, + adv = 0, + bxl = 1, + bst = 2, + jnz = 3, + bxc = 4, + out = 5, + bdv = 6, + cdv = 7, + nop = 8, }; auto opcode_to_str(opcode op) -> char const* { @@ -59,18 +60,25 @@ public: auto clock() -> void { auto const op = read(); + if (peek() == opcode::nop) return; + auto const x = combo(); switch (op) { - case opcode::adv: adv(); - case opcode::bxl: bxl(); - case opcode::bst: bst(); - case opcode::jnz: jnz(); - case opcode::bxc: bxc(); - case opcode::out: out(); - case opcode::bdv: bdv(); - case opcode::cdv: cdv(); - default: nop(); + case opcode::adv: adv(x); break; + case opcode::bxl: bxl(); break; + case opcode::bst: bst(x); break; + case opcode::jnz: jnz(); break; + case opcode::bxc: bxc(); break; + case opcode::out: out(x); break; + case opcode::bdv: bdv(x); break; + case opcode::cdv: cdv(x); break; + default: nop(); break; } + m_pc += 2; + } + + auto halt() const -> bool { + return peek() == opcode::nop; } auto str() const -> std::string { @@ -86,10 +94,42 @@ public: for (usize i = 0; i < m_program.size(); ++i) { str += fmt::format("{:02x}: ", i); - str += fmt::format("{}\n", opcode_to_str(m_program[i])); + str += fmt::format("{}{}\n", opcode_to_str(m_program[i]), m_pc == i ? " <" : ""); + } + str += "\n"; + + str += " "; + for (usize i = 0; i < 16; ++i) { + str += fmt::format("{:02X}", i); + if (i == 7) str += " "; + else str += " "; + } + str += "\n\n"; + + for (usize i = 0; i < m_output.size() * sizeof(u64); ++i) { + if (i % 16 == 0) str += fmt::format("{:04X}: ", i); + str += fmt::format("{:02X}", *(reinterpret_cast(const_cast(m_output.data())) + i)); + if ((i + 1) % 16 == 0) str += "\n"; + else if ((i + 1) % 8 == 0) str += " "; + else str += " "; + } + if (m_output.size() != 0) + str += "\n"; + + str += "-------------------------------------------------------\n"; + return str; + } + + auto output_str() const -> std::string { + std::string str{}; + for (usize i = 0; i < m_output.size(); ++i) { + str += fmt::format("{}", m_output.at(i)); + if (i < m_output.size() - 1) str += ","; } return str; } + auto output() const -> std::vector const& { return m_output; } + private: auto read() const -> opcode { @@ -102,9 +142,13 @@ private: return m_program[m_pc + 1]; return opcode::nop; } - auto combo() const -> u64 { - return 0; + auto const op = u64(peek()); + if (op < 4) return op; + else if (op == 4) return m_regs.a; + else if (op == 5) return m_regs.b; + else if (op == 6) return m_regs.c; + else return u64(opcode::nop); } private: @@ -112,34 +156,54 @@ private: m_regs.a >>= x; } auto bxl() -> void { - m_regs.b = m_regs.b ^ u64(opcode::bxl); + m_regs.b = m_regs.b ^ u64(peek()); } auto bst(u64 x) -> void { m_regs.b = x % 8; } auto jnz() -> void { - if (m_regs.a == 0) return; - m_pc = u64(opcode::jnz); + if (m_regs.a == 0) + return; + m_pc = u64(peek()) - 2; } auto bxc() -> void { m_regs.b = m_regs.b ^ m_regs.c; } auto out(u64 x) -> void { - + m_output.emplace_back(x % 8); + } + auto bdv(u64 x) -> void { + m_regs.b = m_regs.a >> x; + } + auto cdv(u64 x) -> void { + m_regs.c = m_regs.a >> x; } - auto bdv() -> void {} - auto cdv() -> void {} auto nop() -> void {} private: u64 m_pc{}; uec::regs m_regs{}; std::vector m_program{}; + std::vector m_output{}; }; } +auto part_a(uec::regs const& regs, std::vector const& program) -> void { + uec::cpu cpu{}; + cpu.load(regs, program); + + while (!cpu.halt()) { + // fmt::print("{}", cpu.str()); + // std::cin.get(); + cpu.clock(); + } + fmt::print("{}", cpu.str()); + fmt::print("{}\n", cpu.output_str()); +} + auto aoc24::day17([[maybe_unused]]std::span const& args) -> std::expected { - auto res = aoc::read_text("./dat/24/ex/17.txt"); + // auto res = aoc::read_text("./dat/24/ex/17a.txt"); + auto res = aoc::read_text("./dat/24/ex/17b.txt"); // auto res = aoc::read_text("./dat/24/re/17.txt"); if (!res) return std::unexpected(res.error()); auto const txt = *res; @@ -174,10 +238,10 @@ auto aoc24::day17([[maybe_unused]]std::span const& args) -> std::ex } } - uec::cpu cpu{}; - cpu.load(regs, program); + // part_a(regs, program); - fmt::print("{}", cpu.str()); + uec::cpu cpu{}; + cpu.load({}, program); return {}; }