aoc: 2024 bk
This commit is contained in:
5
dat/24/ex/17b.txt
Normal file
5
dat/24/ex/17b.txt
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
Register A: 117440
|
||||||
|
Register B: 0
|
||||||
|
Register C: 0
|
||||||
|
|
||||||
|
Program: 0,3,5,4,3,0
|
||||||
@@ -15,7 +15,7 @@ set(SOURCES
|
|||||||
"day10.cpp"
|
"day10.cpp"
|
||||||
# "day11.cpp"
|
# "day11.cpp"
|
||||||
"day14.cpp"
|
"day14.cpp"
|
||||||
"day16.cpp"
|
# "day16.cpp"
|
||||||
"day17.cpp"
|
"day17.cpp"
|
||||||
)
|
)
|
||||||
add_library(aoc24 STATIC ${HEADERS} ${SOURCES})
|
add_library(aoc24 STATIC ${HEADERS} ${SOURCES})
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ auto entry([[maybe_unused]]std::span<char const*> const& args) -> std::expected<
|
|||||||
case 10: return day10(args);
|
case 10: return day10(args);
|
||||||
// case 11: return day11(args);
|
// case 11: return day11(args);
|
||||||
case 14: return day14(args);
|
case 14: return day14(args);
|
||||||
case 16: return day16(args);
|
// case 16: return day16(args);
|
||||||
case 17: return day17(args);
|
case 17: return day17(args);
|
||||||
default:
|
default:
|
||||||
return aoc::make_error(fmt::format("day {}", day), std::errc::not_supported);
|
return aoc::make_error(fmt::format("day {}", day), std::errc::not_supported);
|
||||||
|
|||||||
@@ -2,6 +2,8 @@
|
|||||||
#include <ranges>
|
#include <ranges>
|
||||||
#include <numeric>
|
#include <numeric>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <map>
|
||||||
|
#include <queue>
|
||||||
|
|
||||||
#include "aoc.hpp"
|
#include "aoc.hpp"
|
||||||
#include "aoc/utils.hpp"
|
#include "aoc/utils.hpp"
|
||||||
@@ -18,7 +20,7 @@ struct edge {
|
|||||||
|
|
||||||
auto str() const -> std::string {
|
auto str() const -> std::string {
|
||||||
if (b == 0) return "nil";
|
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 {
|
auto str() const -> std::string {
|
||||||
std::string str{"node {"};
|
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)
|
if (n.b != 0)
|
||||||
str += " n -> " + n.str() + ",";
|
str += ", n → " + n.str();
|
||||||
if (s.b != 0)
|
if (s.b != 0)
|
||||||
str += " s -> " + s.str() + ",";
|
str += ", s → " + s.str();
|
||||||
if (e.b != 0)
|
if (e.b != 0)
|
||||||
str += " e -> " + e.str() + ",";
|
str += ", e → " + e.str();
|
||||||
if (w.b != 0)
|
if (w.b != 0)
|
||||||
str += " w -> " + w.str();
|
str += ", w → " + w.str();
|
||||||
str += " }";
|
str += " }";
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class graph {
|
class graph {
|
||||||
public:
|
public:
|
||||||
graph(std::string const& maze_str) : m_start(0), m_exit(0) {
|
graph(std::string const& maze_str) : m_start(0), m_exit(0) {
|
||||||
@@ -55,6 +58,8 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto vertices() const -> std::vector<node> const& { return m_nodes; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
auto build(std::string const& maze) -> void {
|
auto build(std::string const& maze) -> void {
|
||||||
auto const lines = maze | aoc::split("\n"sv)
|
auto const lines = maze | aoc::split("\n"sv)
|
||||||
@@ -83,7 +88,7 @@ private:
|
|||||||
if (n_e != '#') {
|
if (n_e != '#') {
|
||||||
n.n = {
|
n.n = {
|
||||||
.a = n.id,
|
.a = n.id,
|
||||||
.b = u64((u64(i - 2) << 32) | (j + 1))
|
.b = u64((u64(i) << 32) | (j + 1))
|
||||||
};
|
};
|
||||||
m_edges.emplace_back(n.n);
|
m_edges.emplace_back(n.n);
|
||||||
}
|
}
|
||||||
@@ -97,7 +102,7 @@ private:
|
|||||||
if (e_e != '#') {
|
if (e_e != '#') {
|
||||||
n.e = {
|
n.e = {
|
||||||
.a = n.id,
|
.a = n.id,
|
||||||
.b = u64((u64(i + 1) << 32) | (j - 2))
|
.b = u64((u64(i + 1) << 32) | (j))
|
||||||
};
|
};
|
||||||
m_edges.emplace_back(n.e);
|
m_edges.emplace_back(n.e);
|
||||||
}
|
}
|
||||||
@@ -122,6 +127,30 @@ private:
|
|||||||
u64 m_rows{};
|
u64 m_rows{};
|
||||||
u64 m_cols{};
|
u64 m_cols{};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// auto dfs() -> void {}
|
||||||
|
// auto bfs() -> void {}
|
||||||
|
|
||||||
|
auto dijkstra(graph const& g, u64 source) -> void {
|
||||||
|
std::map<u64, i64> dist{};
|
||||||
|
std::map<u64, i64> prev{};
|
||||||
|
for (auto const& v : g.vertices()) {
|
||||||
|
dist.insert({v.id, aoc::lim<i64>::max()});
|
||||||
|
prev.insert({v.id, -1});
|
||||||
|
}
|
||||||
|
dist[source] = 0;
|
||||||
|
std::queue<node> 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<i64>::max() ? 1 : dist[u.id] + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
auto aoc24::day16([[maybe_unused]]std::span<char const*> const& args) -> std::expected<void, aoc::error> {
|
auto aoc24::day16([[maybe_unused]]std::span<char const*> const& args) -> std::expected<void, aoc::error> {
|
||||||
|
|||||||
126
sol/24/day17.cpp
126
sol/24/day17.cpp
@@ -2,6 +2,7 @@
|
|||||||
#include <ranges>
|
#include <ranges>
|
||||||
#include <numeric>
|
#include <numeric>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
#include "aoc.hpp"
|
#include "aoc.hpp"
|
||||||
#include "aoc/utils.hpp"
|
#include "aoc/utils.hpp"
|
||||||
@@ -14,15 +15,15 @@ using namespace std::string_view_literals;
|
|||||||
|
|
||||||
namespace uec {
|
namespace uec {
|
||||||
enum class opcode : u16 {
|
enum class opcode : u16 {
|
||||||
adv,
|
adv = 0,
|
||||||
bxl,
|
bxl = 1,
|
||||||
bst,
|
bst = 2,
|
||||||
jnz,
|
jnz = 3,
|
||||||
bxc,
|
bxc = 4,
|
||||||
out,
|
out = 5,
|
||||||
bdv,
|
bdv = 6,
|
||||||
cdv,
|
cdv = 7,
|
||||||
nop,
|
nop = 8,
|
||||||
};
|
};
|
||||||
|
|
||||||
auto opcode_to_str(opcode op) -> char const* {
|
auto opcode_to_str(opcode op) -> char const* {
|
||||||
@@ -59,18 +60,25 @@ public:
|
|||||||
|
|
||||||
auto clock() -> void {
|
auto clock() -> void {
|
||||||
auto const op = read();
|
auto const op = read();
|
||||||
|
if (peek() == opcode::nop) return;
|
||||||
|
|
||||||
|
auto const x = combo();
|
||||||
switch (op) {
|
switch (op) {
|
||||||
case opcode::adv: adv();
|
case opcode::adv: adv(x); break;
|
||||||
case opcode::bxl: bxl();
|
case opcode::bxl: bxl(); break;
|
||||||
case opcode::bst: bst();
|
case opcode::bst: bst(x); break;
|
||||||
case opcode::jnz: jnz();
|
case opcode::jnz: jnz(); break;
|
||||||
case opcode::bxc: bxc();
|
case opcode::bxc: bxc(); break;
|
||||||
case opcode::out: out();
|
case opcode::out: out(x); break;
|
||||||
case opcode::bdv: bdv();
|
case opcode::bdv: bdv(x); break;
|
||||||
case opcode::cdv: cdv();
|
case opcode::cdv: cdv(x); break;
|
||||||
default: nop();
|
default: nop(); break;
|
||||||
}
|
}
|
||||||
|
m_pc += 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto halt() const -> bool {
|
||||||
|
return peek() == opcode::nop;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto str() const -> std::string {
|
auto str() const -> std::string {
|
||||||
@@ -86,10 +94,42 @@ public:
|
|||||||
|
|
||||||
for (usize i = 0; i < m_program.size(); ++i) {
|
for (usize i = 0; i < m_program.size(); ++i) {
|
||||||
str += fmt::format("{:02x}: ", 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;
|
return str;
|
||||||
}
|
}
|
||||||
|
auto output() const -> std::vector<u64> const& { return m_output; }
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
auto read() const -> opcode {
|
auto read() const -> opcode {
|
||||||
@@ -102,9 +142,13 @@ private:
|
|||||||
return m_program[m_pc + 1];
|
return m_program[m_pc + 1];
|
||||||
return opcode::nop;
|
return opcode::nop;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto combo() const -> u64 {
|
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:
|
private:
|
||||||
@@ -112,34 +156,54 @@ private:
|
|||||||
m_regs.a >>= x;
|
m_regs.a >>= x;
|
||||||
}
|
}
|
||||||
auto bxl() -> void {
|
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 {
|
auto bst(u64 x) -> void {
|
||||||
m_regs.b = x % 8;
|
m_regs.b = x % 8;
|
||||||
}
|
}
|
||||||
auto jnz() -> void {
|
auto jnz() -> void {
|
||||||
if (m_regs.a == 0) return;
|
if (m_regs.a == 0)
|
||||||
m_pc = u64(opcode::jnz);
|
return;
|
||||||
|
m_pc = u64(peek()) - 2;
|
||||||
}
|
}
|
||||||
auto bxc() -> void {
|
auto bxc() -> void {
|
||||||
m_regs.b = m_regs.b ^ m_regs.c;
|
m_regs.b = m_regs.b ^ m_regs.c;
|
||||||
}
|
}
|
||||||
auto out(u64 x) -> void {
|
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 {}
|
auto nop() -> void {}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
u64 m_pc{};
|
u64 m_pc{};
|
||||||
uec::regs m_regs{};
|
uec::regs m_regs{};
|
||||||
std::vector<opcode> m_program{};
|
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 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");
|
// 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;
|
||||||
@@ -174,10 +238,10 @@ auto aoc24::day17([[maybe_unused]]std::span<char const*> const& args) -> std::ex
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uec::cpu cpu{};
|
// part_a(regs, program);
|
||||||
cpu.load(regs, program);
|
|
||||||
|
|
||||||
fmt::print("{}", cpu.str());
|
uec::cpu cpu{};
|
||||||
|
cpu.load({}, program);
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user