aoc: 2024 bk
This commit is contained in:
126
sol/24/day17.cpp
126
sol/24/day17.cpp
@@ -2,6 +2,7 @@
|
||||
#include <ranges>
|
||||
#include <numeric>
|
||||
#include <memory>
|
||||
#include <iostream>
|
||||
|
||||
#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<u8*>(const_cast<u64*>(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<u64> 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<opcode> m_program{};
|
||||
std::vector<u64> m_output{};
|
||||
};
|
||||
}
|
||||
|
||||
auto part_a(uec::regs const& regs, std::vector<uec::opcode> 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<char const*> const& args) -> std::expected<void, aoc::error> {
|
||||
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<char const*> 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 {};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user