error checking for Grid
This commit is contained in:
parent
9601c42fc5
commit
833f496090
|
@ -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.
|
||||||
|
|
|
@ -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++) {
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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; }
|
||||||
|
|
|
@ -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;
|
||||||
while (std::getline(in, line)) {
|
if (std::getline(in, line)) {
|
||||||
|
result.columns = line.size();
|
||||||
result.rows.emplace_back(std::move(line));
|
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};
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename F>
|
template <typename F>
|
||||||
|
|
Loading…
Reference in New Issue
Block a user