169 lines
4.4 KiB
C++
169 lines
4.4 KiB
C++
#include <vector>
|
|
#include <ranges>
|
|
#include <numeric>
|
|
#include <memory>
|
|
#include <map>
|
|
#include <queue>
|
|
|
|
#include "aoc.hpp"
|
|
#include "aoc/utils.hpp"
|
|
#include "fmt/format.h"
|
|
#include "stb_image_write.h"
|
|
|
|
using namespace aoc::types;
|
|
using namespace std::string_view_literals;
|
|
|
|
namespace rme {
|
|
struct edge {
|
|
u64 a{0x00};
|
|
u64 b{0x00};
|
|
|
|
auto str() const -> std::string {
|
|
if (b == 0) return "nil";
|
|
return fmt::format("{}.{}", (b >> 32), b & 0xFFFFFFFF);
|
|
}
|
|
};
|
|
|
|
struct node {
|
|
u64 id;
|
|
edge n;
|
|
edge s;
|
|
edge e;
|
|
edge w;
|
|
|
|
auto str() const -> std::string {
|
|
std::string str{"node {"};
|
|
str += " id: " + fmt::format("{}.{}", (id >> 32) & 0xFFFFFFFF, id & 0xFFFFFFFF);
|
|
if (n.b != 0)
|
|
str += ", n → " + n.str();
|
|
if (s.b != 0)
|
|
str += ", s → " + s.str();
|
|
if (e.b != 0)
|
|
str += ", e → " + e.str();
|
|
if (w.b != 0)
|
|
str += ", w → " + w.str();
|
|
str += " }";
|
|
return str;
|
|
}
|
|
};
|
|
|
|
|
|
class graph {
|
|
public:
|
|
graph(std::string const& maze_str) : m_start(0), m_exit(0) {
|
|
build(maze_str);
|
|
|
|
for (auto const& node : m_nodes) {
|
|
fmt::print("{}\n", node.str());
|
|
}
|
|
}
|
|
|
|
auto vertices() const -> std::vector<node> const& { return m_nodes; }
|
|
|
|
private:
|
|
auto build(std::string const& maze) -> void {
|
|
auto const lines = maze | aoc::split("\n"sv)
|
|
| aoc::map_to_sv
|
|
| aoc::filter_non_empty
|
|
| std::ranges::to<std::vector>();
|
|
|
|
m_rows = lines.size();
|
|
for (usize i = 0; i < lines.size(); ++i) {
|
|
auto const& str = lines[i];
|
|
m_cols = str.size();
|
|
for (usize j = 0; j < m_cols; ++j) {
|
|
auto const c = str[j];
|
|
node n{};
|
|
auto const id = u64((u64(i + 1) << 32) | (j + 1));
|
|
if (c == '#' || c == '\n') continue;
|
|
if (c == 'S') m_start = id;
|
|
if (c == 'E') m_exit = id;
|
|
n.id = id;
|
|
|
|
auto const n_e = lines[i - 1][j];
|
|
auto const s_e = lines[i + 1][j];
|
|
auto const e_e = lines[i][j - 1];
|
|
auto const w_e = lines[i][j + 1];
|
|
|
|
if (n_e != '#') {
|
|
n.n = {
|
|
.a = n.id,
|
|
.b = u64((u64(i) << 32) | (j + 1))
|
|
};
|
|
m_edges.emplace_back(n.n);
|
|
}
|
|
if (s_e != '#') {
|
|
n.s = {
|
|
.a = n.id,
|
|
.b = u64((u64(i + 2) << 32) | (j + 1))
|
|
};
|
|
m_edges.emplace_back(n.s);
|
|
}
|
|
if (e_e != '#') {
|
|
n.e = {
|
|
.a = n.id,
|
|
.b = u64((u64(i + 1) << 32) | (j))
|
|
};
|
|
m_edges.emplace_back(n.e);
|
|
}
|
|
if (w_e != '#') {
|
|
n.w = {
|
|
.a = n.id,
|
|
.b = u64((u64(i + 1) << 32) | (j + 2))
|
|
};
|
|
m_edges.emplace_back(n.w);
|
|
}
|
|
|
|
m_nodes.emplace_back(std::move(n));
|
|
}
|
|
}
|
|
}
|
|
|
|
private:
|
|
u64 m_start;
|
|
u64 m_exit;
|
|
std::vector<node> m_nodes{};
|
|
std::vector<edge> m_edges{};
|
|
u64 m_rows{};
|
|
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 res = aoc::read_text("./dat/24/ex/16.txt");
|
|
// auto res = aoc::read_text("./dat/24/re/16.txt");
|
|
if (!res) return std::unexpected(res.error());
|
|
auto const txt = *res;
|
|
|
|
rme::graph g{txt};
|
|
|
|
fmt::print("----------------------------------------\n");
|
|
fmt::print("{}", txt);
|
|
|
|
return {};
|
|
}
|