Make Grid iterable
This commit is contained in:
parent
9e6223f886
commit
d6fc0396cb
@ -17,13 +17,13 @@ auto Part1(aocpp::Grid const &input, std::int64_t reps = 10'000) -> std::int64_t
|
||||
std::unordered_set<aocpp::Coord> infected;
|
||||
|
||||
// Initialize set of infected locations
|
||||
input.each([&infected](auto const pos, auto const cell)
|
||||
for (auto [pos, cell] : input)
|
||||
{
|
||||
if (cell == '#')
|
||||
{
|
||||
infected.insert(pos);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Start in the middle
|
||||
aocpp::Coord pos;
|
||||
@ -62,13 +62,13 @@ auto Part2(aocpp::Grid const &input, std::int64_t reps = 10'000'000) -> std::int
|
||||
std::unordered_map<aocpp::Coord, char> cells;
|
||||
|
||||
// Initialize set of infected locations
|
||||
input.each([&cells](auto const pos, auto const cell)
|
||||
for (auto [pos, cell] : input)
|
||||
{
|
||||
if (cell == '#')
|
||||
{
|
||||
cells.try_emplace(pos, '#');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Start in the middle
|
||||
aocpp::Coord pos;
|
||||
|
@ -60,11 +60,11 @@ Game::Game(Grid grid)
|
||||
, debug_out_{}
|
||||
{
|
||||
// set each unit to its initial hit points
|
||||
grid_.each([&](auto k, auto v) {
|
||||
for (auto [k, v] : grid_) {
|
||||
if (IsUnit(v)) {
|
||||
units_[k] = initial_hp;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Render the game as seen in the examples
|
||||
@ -166,9 +166,9 @@ auto Game::Simulate() -> std::optional<int> {
|
||||
|
||||
// Detect when no targets remain for this unit and end the game
|
||||
auto game_over = true;
|
||||
grid_.each([&](auto k, auto v) {
|
||||
for (auto [k, v] : grid_) {
|
||||
if (IsOpposed(active_team, v)) game_over = false;
|
||||
});
|
||||
}
|
||||
if (game_over) {
|
||||
int total_hp = 0;
|
||||
for (auto const& [_,v] : units_) { total_hp += v; }
|
||||
|
12
2019/10.cpp
12
2019/10.cpp
@ -70,23 +70,23 @@ auto ClearView(Grid const& grid, Coord src, Coord dst) -> bool {
|
||||
auto Part1(Grid const& grid) {
|
||||
std::size_t best = 0;
|
||||
Coord base {};
|
||||
grid.each([&](Coord src, char s) {
|
||||
for (auto [src, s] : grid) {
|
||||
if ('#' == s) {
|
||||
std::size_t visible = 0;
|
||||
grid.each([&](Coord dst, char d){
|
||||
for (auto [dst, d] : grid) {
|
||||
if ('#' == d && src != dst) {
|
||||
if (ClearView(grid, src, dst)) {
|
||||
visible++;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (visible > best) {
|
||||
best = visible;
|
||||
base = src;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
return std::make_pair(best, base);
|
||||
}
|
||||
|
||||
@ -94,11 +94,11 @@ auto Part2(Grid const& grid, Coord base, std::size_t n) {
|
||||
std::map<Rational<std::int64_t>, std::vector<Coord>> targets;
|
||||
|
||||
// arrange all the other asteroids by their angle relative to the base
|
||||
grid.each([&](Coord c, char v){
|
||||
for (auto [c, v] : grid){
|
||||
if (c != base && v == '#') {
|
||||
targets[angle(c-base)].push_back(c);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Sort to vectors per angle such that the nearest asteroids are at
|
||||
// the end of the list
|
||||
|
@ -66,14 +66,14 @@ auto ComputePath(Grid const& grid)
|
||||
{
|
||||
// Determine starting location and direction
|
||||
Coord start{}, step{};
|
||||
grid.each([&](Coord c, char v) {
|
||||
for (auto [c, v] : grid) {
|
||||
switch (v) {
|
||||
case '^': start = c; step = { 0, -1}; break;
|
||||
case '>': start = c; step = { 0, 1}; break;
|
||||
case '<': start = c; step = {-1, 0}; break;
|
||||
case 'v': start = c; step = { 0, 1}; break;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
auto is_path = [&](Coord c) {
|
||||
return grid.contains(c) && grid[c] == '#';
|
||||
|
@ -41,11 +41,11 @@ auto SetKey(Doors& doors, char key) {
|
||||
|
||||
auto FindFeatures(Grid const& grid) -> Features {
|
||||
Features features;
|
||||
grid.each([&](Coord c, char v) {
|
||||
for (auto [c, v] : grid) {
|
||||
if ('#' != v && '.' != v) {
|
||||
features[v] = c;
|
||||
}
|
||||
});
|
||||
}
|
||||
return features;
|
||||
}
|
||||
|
||||
|
@ -27,9 +27,9 @@ auto FindBugs(Grid const& grid) -> std::vector<Coord> {
|
||||
std::int64_t w = grid.Cols();
|
||||
std::int64_t h = grid.Rows();
|
||||
|
||||
grid.each([&](Coord c, char v) {
|
||||
for (auto [c, v] : grid) {
|
||||
if (v == '#') result.push_back(c);
|
||||
});
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -22,7 +22,7 @@ Dir directions[4] {Up, Down, Left, Right};
|
||||
auto Part1(Grid const& grid) -> std::int64_t
|
||||
{
|
||||
std::int64_t result {0};
|
||||
grid.each([&](Coord const c, char const v) {
|
||||
for (auto [c, v] : grid) {
|
||||
result += std::any_of(
|
||||
std::begin(directions), std::end(directions),
|
||||
[&](Dir const dir) {
|
||||
@ -31,14 +31,14 @@ auto Part1(Grid const& grid) -> std::int64_t
|
||||
}
|
||||
return true;
|
||||
});
|
||||
});
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
auto Part2(Grid const& grid) -> std::int64_t
|
||||
{
|
||||
std::int64_t result {0};
|
||||
grid.each([&](Coord const c, char const v) {
|
||||
for (auto [c, v] : grid) {
|
||||
auto score = std::transform_reduce(
|
||||
std::begin(directions), std::end(directions),
|
||||
std::int64_t{1}, std::multiplies(), // product
|
||||
@ -51,7 +51,7 @@ auto Part2(Grid const& grid) -> std::int64_t
|
||||
return count;
|
||||
});
|
||||
if (result < score) result = score;
|
||||
});
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -27,13 +27,13 @@ auto Parse(std::istream & in) -> std::tuple<Coord, std::vector<Coord>, Coord, Gr
|
||||
auto& end = std::get<2>(result);
|
||||
auto& grid = std::get<3>(result);
|
||||
|
||||
grid.each([&](Coord c, char v) {
|
||||
for (auto [c, v] : grid) {
|
||||
switch (v) {
|
||||
case 'S': grid[c] = 'a'; start1 = c; break;
|
||||
case 'E': grid[c] = 'z'; end = c; break;
|
||||
case 'a': starts2.push_back(c); break;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -1,3 +1,3 @@
|
||||
add_library(aocpp src/Startup.cpp src/Coord.cpp src/Parsing.cpp)
|
||||
add_library(aocpp src/Startup.cpp src/Coord.cpp src/Parsing.cpp src/Grid.cpp)
|
||||
target_include_directories(aocpp PUBLIC include)
|
||||
target_link_libraries(aocpp Boost::headers)
|
@ -1,7 +1,6 @@
|
||||
#ifndef AOCPP_GRID_HPP_
|
||||
#define AOCPP_GRID_HPP_
|
||||
|
||||
#include <concepts>
|
||||
#include <iostream>
|
||||
#include <stdexcept>
|
||||
#include <type_traits>
|
||||
@ -12,6 +11,31 @@
|
||||
|
||||
namespace aocpp {
|
||||
|
||||
struct Grid;
|
||||
|
||||
struct GridElement {
|
||||
const Coord pos;
|
||||
char elt;
|
||||
};
|
||||
|
||||
class GridIterator {
|
||||
Grid const& grid_;
|
||||
std::int64_t x_, y_;
|
||||
|
||||
public:
|
||||
GridIterator(Grid const& grid, std::int64_t x, std::int64_t y)
|
||||
: grid_{grid}, x_{x}, y_{y} {}
|
||||
|
||||
auto operator++() -> GridIterator&;
|
||||
|
||||
auto operator*() -> GridElement;
|
||||
|
||||
auto operator==(GridIterator const& rhs) const -> bool
|
||||
{
|
||||
return x_ == rhs.x_ && y_ == rhs.y_;
|
||||
}
|
||||
};
|
||||
|
||||
struct Grid {
|
||||
std::vector<std::string> rows;
|
||||
std::size_t columns;
|
||||
@ -57,28 +81,16 @@ struct Grid {
|
||||
}
|
||||
result.rows.emplace_back(std::move(line));
|
||||
}
|
||||
} else {
|
||||
result.columns = 0;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Apply the callback function across all elements of the grid.
|
||||
*
|
||||
* @tparam F Type of callback
|
||||
* @param f Callback function
|
||||
*/
|
||||
template <std::invocable<Coord, char> F>
|
||||
auto each(F f = F{}) const -> void {
|
||||
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]);
|
||||
}
|
||||
}
|
||||
auto begin() const -> GridIterator {
|
||||
return GridIterator{*this, 0, 0};
|
||||
}
|
||||
|
||||
auto end() const -> GridIterator {
|
||||
return GridIterator{*this, 0, static_cast<std::int64_t>(rows.size())};
|
||||
}
|
||||
};
|
||||
|
||||
|
19
lib/src/Grid.cpp
Normal file
19
lib/src/Grid.cpp
Normal file
@ -0,0 +1,19 @@
|
||||
#include "aocpp/Grid.hpp"
|
||||
|
||||
namespace aocpp {
|
||||
auto GridIterator::operator*() -> GridElement
|
||||
{
|
||||
return {{x_, y_}, grid_[Coord{x_, y_}]};
|
||||
}
|
||||
|
||||
auto GridIterator::operator++() -> GridIterator &
|
||||
{
|
||||
if (++x_ == grid_.columns)
|
||||
{
|
||||
x_ = 0;
|
||||
y_++;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
} // namespace
|
Loading…
Reference in New Issue
Block a user