aoc24: day06a complete

This commit is contained in:
2024-12-09 01:27:55 +01:00
parent a35123500e
commit 57d9bdf0f3
2 changed files with 150 additions and 2 deletions

View File

@@ -1,7 +1,149 @@
#include <vector>
#include <algorithm>
#include <ranges>
#include <numeric>
#include <cmath>
#include <utility>
#include "aoc.hpp"
#include "aoc/utils.hpp"
#include "fmt/format.h"
auto aoc24::day06([[maybe_unused]]std::span<char const*> const& args) -> std::expected<void, aoc::error> {
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::vector>();
}) | std::ranges::to<std::vector>();
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<u8> 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<u8> 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<char const*> const& args) -> std::expected<void, aoc::error> {
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 {};
}