error checking for Grid

This commit is contained in:
Eric Mertens 2022-11-28 09:20:50 -08:00
parent 9601c42fc5
commit 833f496090
5 changed files with 42 additions and 12 deletions

View File

@ -17,7 +17,7 @@ namespace {
auto GatherOutput(Machine m) -> Grid auto GatherOutput(Machine m) -> Grid
{ {
Grid grid; std::vector<std::string> rows;
bool eol = true; // next output starts a new line bool eol = true; // next output starts a new line
Run(m, []() -> ValueType { Run(m, []() -> ValueType {
@ -25,16 +25,16 @@ auto GatherOutput(Machine m) -> Grid
}, },
[&](ValueType c) -> void { [&](ValueType c) -> void {
if (eol) { if (eol) {
grid.rows.emplace_back(); rows.emplace_back();
eol = false; eol = false;
} }
if ('\n' == c) { if ('\n' == c) {
eol = true; eol = true;
} else { } else {
grid.rows.back().push_back(static_cast<char>(c));} rows.back().push_back(static_cast<char>(c));}
} }
); );
return grid; return Grid{std::move(rows)};
} }
/// Find all the 4-way intersections. /// Find all the 4-way intersections.

View File

@ -35,8 +35,8 @@ using Distances = std::map<Name,std::vector<std::pair<Name, std::int64_t>>>;
auto FindPortals(Grid const& grid) -> Portals { auto FindPortals(Grid const& grid) -> Portals {
Portals portals; Portals portals;
std::int64_t w = grid.rows[0].size(); std::int64_t w = grid.Cols();
std::int64_t h = grid.rows.size(); std::int64_t h = grid.Rows();
for (std::int64_t x = 1; x < w-1; x++) { for (std::int64_t x = 1; x < w-1; x++) {
for (std::int64_t y = 1; y < h-1; y++) { for (std::int64_t y = 1; y < h-1; y++) {

View File

@ -24,8 +24,8 @@ namespace {
auto FindBugs(Grid const& grid) -> std::vector<Coord> { auto FindBugs(Grid const& grid) -> std::vector<Coord> {
std::vector<Coord> result; std::vector<Coord> result;
std::int64_t w = grid.rows[0].size(); std::int64_t w = grid.Cols();
std::int64_t h = grid.rows.size(); std::int64_t h = grid.Rows();
grid.each([&](Coord c, char v) { grid.each([&](Coord c, char v) {
if (v == '#') result.push_back(c); if (v == '#') result.push_back(c);

View File

@ -22,11 +22,12 @@ namespace {
auto Ski(Grid const& grid, Coord step) -> std::size_t auto Ski(Grid const& grid, Coord step) -> std::size_t
{ {
std::size_t const w = grid.rows[0].size(); std::size_t const w = grid.Cols();
std::size_t const h = grid.Rows();
std::size_t trees {0}; std::size_t trees {0};
Coord here {0,0}; Coord here {0,0};
while(here.y < grid.rows.size()) { while(here.y < h) {
if (grid[here] == '#') trees++; if (grid[here] == '#') trees++;
here += step; here += step;
while (here.x >= w) { here.x -= w; } while (here.x >= w) { here.x -= w; }

View File

@ -5,6 +5,7 @@
#include <vector> #include <vector>
#include <utility> #include <utility>
#include <type_traits> #include <type_traits>
#include <stdexcept>
#include <aocpp/Coord.hpp> #include <aocpp/Coord.hpp>
@ -12,6 +13,21 @@ namespace aocpp {
struct Grid { struct Grid {
std::vector<std::string> rows; 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 { auto contains(Coord c) const -> bool {
return return
@ -24,13 +40,26 @@ struct Grid {
auto operator[](Coord c) -> char& { return rows[c.y][c.x]; } auto operator[](Coord c) -> char& { return rows[c.y][c.x]; }
auto operator[](Coord c) const -> 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 { static auto Parse(std::istream & in) -> Grid {
Grid result; Grid result;
std::string line; std::string line;
if (std::getline(in, line)) {
result.columns = line.size();
result.rows.emplace_back(std::move(line));
while (std::getline(in, line)) { while (std::getline(in, line)) {
if (line.size() != result.columns) {
throw std::runtime_error{"bad grid"};
}
result.rows.emplace_back(std::move(line)); result.rows.emplace_back(std::move(line));
} }
return {result}; } else {
result.columns = 0;
}
return result;
} }
template <typename F> template <typename F>