aoc24: day17 cpu
This commit is contained in:
@@ -93,11 +93,15 @@ using vec = std::vector<T>;
|
|||||||
|
|
||||||
inline constexpr auto split = std::views::split;
|
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));
|
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();
|
return !str.empty();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
132
sol/24/day17.cpp
132
sol/24/day17.cpp
@@ -7,12 +7,13 @@
|
|||||||
#include "aoc/utils.hpp"
|
#include "aoc/utils.hpp"
|
||||||
#include "fmt/format.h"
|
#include "fmt/format.h"
|
||||||
#include "stb_image_write.h"
|
#include "stb_image_write.h"
|
||||||
|
#include "ctre.hpp"
|
||||||
|
|
||||||
using namespace aoc::types;
|
using namespace aoc::types;
|
||||||
using namespace std::string_view_literals;
|
using namespace std::string_view_literals;
|
||||||
|
|
||||||
namespace uec {
|
namespace uec {
|
||||||
enum class opcode : u8 {
|
enum class opcode : u16 {
|
||||||
adv,
|
adv,
|
||||||
bxl,
|
bxl,
|
||||||
bst,
|
bst,
|
||||||
@@ -20,9 +21,24 @@ enum class opcode : u8 {
|
|||||||
bxc,
|
bxc,
|
||||||
out,
|
out,
|
||||||
bdv,
|
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 {
|
struct regs {
|
||||||
u64 a;
|
u64 a;
|
||||||
u64 b;
|
u64 b;
|
||||||
@@ -38,10 +54,85 @@ public:
|
|||||||
m_program = program;
|
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<opcode> const& { return m_program; }
|
auto program() const -> std::vector<opcode> 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:
|
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{};
|
uec::regs m_regs{};
|
||||||
std::vector<opcode> m_program{};
|
std::vector<opcode> m_program{};
|
||||||
};
|
};
|
||||||
@@ -52,8 +143,41 @@ auto aoc24::day17([[maybe_unused]]std::span<char const*> const& args) -> std::ex
|
|||||||
// auto res = aoc::read_text("./dat/24/re/17.txt");
|
// auto res = aoc::read_text("./dat/24/re/17.txt");
|
||||||
if (!res) return std::unexpected(res.error());
|
if (!res) return std::unexpected(res.error());
|
||||||
auto const txt = *res;
|
auto const txt = *res;
|
||||||
|
auto const lines = txt | aoc::split("\n"sv)
|
||||||
|
| aoc::map_to_sv
|
||||||
|
| aoc::filter_non_empty
|
||||||
|
| std::ranges::to<std::vector>();
|
||||||
|
|
||||||
auto
|
uec::regs regs{};
|
||||||
|
std::vector<uec::opcode> 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<std::vector>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uec::cpu cpu{};
|
||||||
|
cpu.load(regs, program);
|
||||||
|
|
||||||
|
fmt::print("{}", cpu.str());
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user