81 lines
2.0 KiB
C++
81 lines
2.0 KiB
C++
#ifndef AOCPP_GRID_HPP_
|
|
#define AOCPP_GRID_HPP_
|
|
|
|
#include <iostream>
|
|
#include <vector>
|
|
#include <utility>
|
|
#include <type_traits>
|
|
#include <stdexcept>
|
|
|
|
#include <aocpp/Coord.hpp>
|
|
|
|
namespace aocpp {
|
|
|
|
struct Grid {
|
|
std::vector<std::string> rows;
|
|
std::size_t columns;
|
|
|
|
Grid() : rows{}, columns{} {}
|
|
explicit Grid(std::vector<std::string> rows) : rows(std::move(rows))
|
|
{
|
|
columns = rows.empty() ? 0 : rows[0].size();
|
|
for (std::size_t i = 1; i < rows.size(); i++) {
|
|
if (rows[i].size() != columns) {
|
|
throw std::runtime_error{"grid not rectangular"};
|
|
}
|
|
}
|
|
}
|
|
|
|
auto Rows() const -> std::size_t { return rows.size(); }
|
|
auto Cols() const -> std::size_t { return columns; }
|
|
|
|
auto contains(Coord c) const -> bool {
|
|
return
|
|
0 <= c.x
|
|
&& 0 <= c.y
|
|
&& c.y < rows.size()
|
|
&& c.x < rows[c.y].size();
|
|
}
|
|
|
|
auto operator[](Coord c) -> char& { return rows[c.y][c.x]; }
|
|
auto operator[](Coord c) const -> char { return rows[c.y][c.x]; }
|
|
|
|
/// @brief Parse a rectangular grid from a stream
|
|
/// @param in input stream read until eof
|
|
/// @return parsed grid
|
|
/// @throw std::runtime\_error when grid is not rectangular
|
|
static auto Parse(std::istream & in) -> Grid {
|
|
Grid result;
|
|
std::string line;
|
|
if (std::getline(in, line)) {
|
|
result.columns = line.size();
|
|
result.rows.emplace_back(std::move(line));
|
|
while (std::getline(in, line)) {
|
|
if (line.size() != result.columns) {
|
|
throw std::runtime_error{"bad grid"};
|
|
}
|
|
result.rows.emplace_back(std::move(line));
|
|
}
|
|
} else {
|
|
result.columns = 0;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
template <typename F>
|
|
auto each(F f = F{}) const {
|
|
auto const h = rows.size();
|
|
for (std::size_t y = 0; y < h; y++) {
|
|
auto const& row = rows[y];
|
|
auto const w = row.size();
|
|
for (std::size_t x = 0; x < w; x++) {
|
|
f(Coord{static_cast<std::int64_t>(x), static_cast<std::int64_t>(y)}, row[x]);
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
}
|
|
|
|
#endif
|