From da8a4cc5dec0b912d8c76161d6b821ed86d37c21 Mon Sep 17 00:00:00 2001 From: Pratchaya Khansomboon Date: Wed, 18 Dec 2024 21:53:42 +0100 Subject: [PATCH] aoc24: day17 cpu --- aoc/utils.hpp | 8 ++- sol/24/day17.cpp | 132 +++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 134 insertions(+), 6 deletions(-) diff --git a/aoc/utils.hpp b/aoc/utils.hpp index 1210949..373cbf3 100644 --- a/aoc/utils.hpp +++ b/aoc/utils.hpp @@ -93,11 +93,15 @@ using vec = std::vector; inline constexpr auto split = std::views::split; -constexpr auto map_to_sv = std::views::transform([](auto const& str) { +[[maybe_unused]]constexpr auto map_to_str = std::views::transform([](auto const& str) { + return std::string(std::begin(str), std::end(str)); +}); + +[[maybe_unused]]constexpr auto map_to_sv = std::views::transform([](auto const& str) { return std::string_view(std::begin(str), std::end(str)); }); -constexpr auto filter_non_empty = std::views::filter([](auto const& str) { +[[maybe_unused]]constexpr auto filter_non_empty = std::views::filter([](auto const& str) { return !str.empty(); }); } diff --git a/sol/24/day17.cpp b/sol/24/day17.cpp index 7f6b277..0065409 100644 --- a/sol/24/day17.cpp +++ b/sol/24/day17.cpp @@ -7,12 +7,13 @@ #include "aoc/utils.hpp" #include "fmt/format.h" #include "stb_image_write.h" +#include "ctre.hpp" using namespace aoc::types; using namespace std::string_view_literals; namespace uec { -enum class opcode : u8 { +enum class opcode : u16 { adv, bxl, bst, @@ -20,9 +21,24 @@ enum class opcode : u8 { bxc, out, bdv, - cdv + cdv, + nop, }; +auto opcode_to_str(opcode op) -> char const* { + switch (op) { + case opcode::adv: return "adv"; + case opcode::bxl: return "bxl"; + case opcode::bst: return "bst"; + case opcode::jnz: return "jnz"; + case opcode::bxc: return "bxc"; + case opcode::out: return "out"; + case opcode::bdv: return "bdv"; + case opcode::cdv: return "cdv"; + default: return "nop"; + } +} + struct regs { u64 a; u64 b; @@ -38,10 +54,85 @@ public: m_program = program; } - auto registers() const -> uec::regs { return m_regs; } + auto registers() const -> uec::regs const& { return m_regs; } auto program() const -> std::vector const& { return m_program; } + auto clock() -> void { + auto const op = read(); + + 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(); + } + } + + auto str() const -> std::string { + using namespace std::string_literals; + std::string str{}; + str += "PC: " + fmt::format("{:#04x}", m_pc) + "\n"; + str += "\n"; + + str += "A: " + fmt::format("{:#010x}", m_regs.a) + "\n"; + str += "B: " + fmt::format("{:#010x}", m_regs.b) + "\n"; + str += "C: " + fmt::format("{:#010x}", m_regs.c) + "\n"; + str += "\n"; + + for (usize i = 0; i < m_program.size(); ++i) { + str += fmt::format("{:02x}: ", i); + str += fmt::format("{}\n", opcode_to_str(m_program[i])); + } + return str; + } + private: + auto read() const -> opcode { + if (m_pc < m_program.size()) + return m_program[m_pc]; + return opcode::nop; + } + auto peek() const -> opcode { + if (m_pc + 1 < m_program.size()) + return m_program[m_pc + 1]; + return opcode::nop; + } + + auto combo() const -> u64 { + return 0; + } + +private: + auto adv(u64 x) -> void { + m_regs.a >>= x; + } + auto bxl() -> void { + m_regs.b = m_regs.b ^ u64(opcode::bxl); + } + auto bst(u64 x) -> void { + m_regs.b = x % 8; + } + auto jnz() -> void { + if (m_regs.a == 0) return; + m_pc = u64(opcode::jnz); + } + auto bxc() -> void { + m_regs.b = m_regs.b ^ m_regs.c; + } + auto out(u64 x) -> void { + + } + auto bdv() -> void {} + auto cdv() -> void {} + auto nop() -> void {} + +private: + u64 m_pc{}; uec::regs m_regs{}; std::vector m_program{}; }; @@ -52,8 +143,41 @@ auto aoc24::day17([[maybe_unused]]std::span const& args) -> std::ex // auto res = aoc::read_text("./dat/24/re/17.txt"); if (!res) return std::unexpected(res.error()); auto const txt = *res; + auto const lines = txt | aoc::split("\n"sv) + | aoc::map_to_sv + | aoc::filter_non_empty + | std::ranges::to(); - auto + uec::regs regs{}; + std::vector program{}; + for (auto const& line : lines) { + if (auto reg = ctre::match<"Register ([A-Z]): ([0-9]+)">(line)) { + if (reg.get<1>().view() == "A"sv) { + regs.a = std::stoul(reg.get<2>().to_string()); + } else if (reg.get<1>().view() == "A"sv) { + regs.b = std::stoul(reg.get<2>().to_string()); + } else if (reg.get<1>().view() == "A"sv) { + regs.c = std::stoul(reg.get<2>().to_string()); + } else { + // fmt::print("unknown register\n"); + } + continue; + } + + if (auto prog = ctre::match<"Program: ([0-9,]+)">(line)) { + program = prog.get<1>().to_string() | aoc::split(","sv) + | aoc::map_to_str + | aoc::filter_non_empty + | std::views::transform([](auto const& str) { + return uec::opcode(std::stoul(str)); + }) | std::ranges::to(); + } + } + + uec::cpu cpu{}; + cpu.load(regs, program); + + fmt::print("{}", cpu.str()); return {}; }