diff --git a/aoc/utils.hpp b/aoc/utils.hpp index 596b410..6d79cb7 100644 --- a/aoc/utils.hpp +++ b/aoc/utils.hpp @@ -23,6 +23,9 @@ using u16 = std::uint16_t; using u32 = std::uint32_t; using u64 = std::uint64_t; +using usize = std::size_t; +using isize = std::ptrdiff_t; + using i8 = std::int8_t; using i16 = std::int16_t; using i32 = std::int32_t; @@ -40,6 +43,9 @@ using u16 = types::u16; using u32 = types::u32; using u64 = types::u64; +using usize = types::usize; +using isize = types::isize; + using i8 = types::i8; using i16 = types::i16; using i32 = types::i32; diff --git a/sol/24/day06.cpp b/sol/24/day06.cpp index acc03b3..b0c1448 100644 --- a/sol/24/day06.cpp +++ b/sol/24/day06.cpp @@ -1,7 +1,149 @@ +#include +#include +#include +#include +#include +#include + #include "aoc.hpp" #include "aoc/utils.hpp" #include "fmt/format.h" -auto aoc24::day06([[maybe_unused]]std::span const& args) -> std::expected { - return aoc::make_error("day 5", std::errc::not_supported); +using namespace std::string_view_literals; +using namespace aoc::types; + +namespace lab { + +class guard { +public: + guard(i64 x, i64 y) : m_row(y), m_col(x) { } + + auto set_direction(i64 x, i64 y) -> void { + m_dx = x; + m_dy = y; + } + auto set_dx(i64 x) -> void { m_dx = x; } + auto set_dy(i64 y) -> void { m_dy = y; } + auto set_x(i64 v) -> void { m_col = v; } + auto set_y(i64 v) -> void { m_row = v; } + auto x() const -> i64 { return m_col; } + auto y() const -> i64 { return m_row; } + auto dx() const -> i64 { return m_dx; } + auto dy() const -> i64 { return m_dy; } + + auto move() -> void { + m_row += m_dy; + m_col += m_dx; + } + +private: + i64 m_row; + i64 m_col; + i64 m_dx; + i64 m_dy; +}; + +class lab { +public: + lab(std::string const& map_str) { + auto const lines = map_str + | std::views::split("\n"sv) + | std::views::transform([](auto const& str) { + return std::string_view(std::begin(str), std::end(str)); + }) + | std::views::filter([](auto const& str) { return !str.empty(); }) + | std::views::transform([](auto const& str) { + return str | std::views::filter([](auto const& ch) { return ch != '\n'; }) + | std::ranges::to(); + }) | std::ranges::to(); + + m_rows = lines.size(); + m_cols = lines[0].size(); + std::ranges::for_each(lines, [&](auto const& str) { + std::ranges::for_each(str, [&](auto const& ch) { + m_data.emplace_back(ch); + }); + }); + + auto it = std::find_if(std::begin(m_data), std::end(m_data), [](auto const ch) { return ch == '^'; }); + if (it != std::end(m_data)) m_start.set_direction(0, -1); + + auto const dist = usize(it - std::begin(m_data)); + m_start.set_x(i64(dist - (dist / m_cols * m_rows))); + m_start.set_y(i64(dist / m_cols)); + } + + auto start() const -> guard { return m_start; } + auto rows() const -> usize { return m_rows; } + auto cols() const -> usize { return m_cols; } + + auto is_obstruction(usize x, usize y) const -> bool { + if (x >= m_cols || y >= m_rows) return false; + return m_data[y * m_cols + x] == '#'; + } + + auto is_obstruction(guard const& g) const -> bool { + return is_obstruction(usize(g.x()), usize(g.y())); + } + + auto is_outside(usize x, usize y) const -> bool { + return x >= m_cols || y >= m_rows; + } + + auto is_outside(guard const& g) const -> bool { + return is_outside(usize(g.x()), usize(g.y())); + } + +private: + usize m_rows{}; + usize m_cols{}; + std::vector m_data{}; + guard m_start{0, 0}; +}; +} + +auto part_a(lab::lab const& map) -> void { + // for (usize i = 0; i < map.rows; ++i) { + // for (usize j = 0; j < map.cols; ++j) { + // fmt::print("{} ", c8(map.data[i * map.cols + j])); + // } + // fmt::print("\n"); + // } + std::vector cpy{}; + cpy.resize(map.rows() * map.cols()); + std::fill(std::begin(cpy), std::end(cpy), 0); + + auto guard = map.start(); + + while (!map.is_outside(guard)) { + cpy[usize(guard.y()) * map.cols() + usize(guard.x())] = 1; + lab::guard guard_cpy = guard; + guard_cpy.move(); + + if (map.is_obstruction(guard_cpy)) { + if (guard_cpy.dy() == -1) + guard.set_direction(1, 0); + else if (guard_cpy.dy() == 1) + guard.set_direction(-1, 0); + else if (guard_cpy.dx() == -1) + guard.set_direction(0, -1); + else if (guard_cpy.dx() == 1) + guard.set_direction(0, 1); + } + guard.move(); + } + + auto const sum = std::accumulate(std::begin(cpy), std::end(cpy), 0); + fmt::print("Part A: {}\n", sum); +} + +auto aoc24::day06([[maybe_unused]]std::span const& args) -> std::expected { + auto res = aoc::read_text("./dat/24/re/06.txt"); + if (!res) return std::unexpected(res.error()); + auto const map_txt = *res; + + lab::lab map{map_txt}; + part_a(map); + + return {}; }