fiddle with 2022-12
This commit is contained in:
parent
de648bc578
commit
de2117327e
47
2022/12.cpp
47
2022/12.cpp
|
@ -1,5 +1,6 @@
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <optional>
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
|
@ -16,55 +17,47 @@ using aocpp::Grid;
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
auto Parse(std::istream & in) -> std::tuple<Coord, Coord, Grid>
|
auto Parse(std::istream & in) -> std::tuple<Coord, std::vector<Coord>, Coord, Grid>
|
||||||
{
|
{
|
||||||
Coord start {};
|
Coord start1 {};
|
||||||
|
std::vector<Coord> starts2;
|
||||||
Coord end {};
|
Coord end {};
|
||||||
auto grid = Grid::Parse(in);
|
auto grid = Grid::Parse(in);
|
||||||
|
|
||||||
grid.each([&](Coord c, char v) {
|
grid.each([&](Coord c, char v) {
|
||||||
switch (v) {
|
switch (v) {
|
||||||
case 'S': grid[c] = 'a'; start = c; break;
|
case 'S': grid[c] = 'a'; start1 = c; break;
|
||||||
case 'E': grid[c] = 'z'; end = c; break;
|
case 'E': grid[c] = 'z'; end = c; break;
|
||||||
|
case 'a': starts2.push_back(c); break;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return {start, end, std::move(grid)};
|
return {start1, std::move(starts2), end, std::move(grid)};
|
||||||
}
|
}
|
||||||
|
|
||||||
auto Solve(std::vector<Coord> starts, Coord end, Grid const& grid) -> std::int64_t
|
auto Solve(std::vector<Coord> starts, Coord end, Grid const& grid) -> std::optional<std::int64_t>
|
||||||
{
|
{
|
||||||
std::vector<Coord> prev_layer(std::move(starts));
|
|
||||||
std::vector<Coord> next_layer;
|
std::vector<Coord> next_layer;
|
||||||
std::set<Coord> seen;
|
std::set<Coord> seen;
|
||||||
std::int64_t counter {1};
|
std::int64_t counter {1};
|
||||||
|
|
||||||
while (!prev_layer.empty()) {
|
while (!starts.empty()) {
|
||||||
for (auto here : prev_layer) {
|
for (auto here : starts) {
|
||||||
if (!seen.insert(here).second) continue;
|
if (!seen.insert(here).second) continue;
|
||||||
auto here_height = grid[here];
|
auto here_height = grid[here];
|
||||||
for (auto next : {Up(here), Down(here), Left(here), Right(here)}) {
|
for (auto next : {Up(here), Down(here), Left(here), Right(here)}) {
|
||||||
if (!grid.contains(next)) continue;
|
if (!grid.contains(next)) continue;
|
||||||
if (grid[next] - here_height > 1) continue;
|
if (grid[next] - 1 > here_height) continue;
|
||||||
if (next == end) { return counter; }
|
if (next == end) { return counter; }
|
||||||
next_layer.push_back(next);
|
next_layer.push_back(next);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
counter++;
|
counter++;
|
||||||
prev_layer.clear();
|
starts.clear();
|
||||||
std::swap(prev_layer, next_layer);
|
std::swap(starts, next_layer);
|
||||||
}
|
}
|
||||||
|
|
||||||
return -1;
|
return {};
|
||||||
}
|
|
||||||
|
|
||||||
auto Part2Starts(Grid const& grid) -> std::vector<Coord>
|
|
||||||
{
|
|
||||||
std::vector<Coord> starts;
|
|
||||||
grid.each([&](Coord c, char v) {
|
|
||||||
if (v == 'a') starts.push_back(c);
|
|
||||||
});
|
|
||||||
return starts;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
@ -78,15 +71,15 @@ TEST_SUITE("2022-12 examples") {
|
||||||
"acctuvwj\n"
|
"acctuvwj\n"
|
||||||
"abdefghi\n"
|
"abdefghi\n"
|
||||||
};
|
};
|
||||||
auto [start, end, grid] = Parse(in);
|
auto [start1, starts2, end, grid] = Parse(in);
|
||||||
CHECK(31 == Solve({start}, end, grid));
|
CHECK(31 == Solve({start1}, end, grid));
|
||||||
CHECK(29 == Solve(Part2Starts(grid), end, grid));
|
CHECK(29 == Solve(std::move(starts2), end, grid));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto Main(std::istream & in, std::ostream & out) -> void
|
auto Main(std::istream & in, std::ostream & out) -> void
|
||||||
{
|
{
|
||||||
auto const [start, end, grid] = Parse(in);
|
auto [start1, starts2, end, grid] = Parse(in);
|
||||||
out << "Part 1: " << Solve({start}, end, grid) << std::endl;
|
out << "Part 1: " << Solve({start1}, end, grid).value_or(-1) << std::endl;
|
||||||
out << "Part 2: " << Solve(Part2Starts(grid), end, grid) << std::endl;
|
out << "Part 2: " << Solve(std::move(starts2), end, grid).value_or(-1) << std::endl;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user