Skip to content

Commit

Permalink
2023: day 23 part 2 complete
Browse files Browse the repository at this point in the history
  • Loading branch information
yut23 committed Jan 27, 2024
1 parent 47b53be commit e014dac
Show file tree
Hide file tree
Showing 5 changed files with 80 additions and 8 deletions.
1 change: 1 addition & 0 deletions 2023/answer_tests/day23/example1.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
Day 23:
94
154
3 changes: 3 additions & 0 deletions 2023/answer_tests/day23/example2.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Day 23:
33
41
12 changes: 12 additions & 0 deletions 2023/input/day23/example2.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#.#########
#v#...#...#
#.>.#...#.#
#v#######v#
#.###...<.#
#v###v###v#
#.>.>.>.>.#
#v###v###v#
#.###.###v#
#.>.#v#.>.#
###.>.>.#v#
#########.#
8 changes: 7 additions & 1 deletion 2023/src/day23.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,16 @@ void solve(int argc, char **argv, bool print) {
if (print) {
std::cout << part_1 << "\n";
}

int part_2 = trail_map.part_2();
if (print) {
std::cout << part_2 << "\n";
}
}

int main(int argc, char **argv) {
constexpr int N = aoc::FAST ? 1000 : 1;
// constexpr int N = aoc::FAST ? 1000 : 1;
constexpr int N = 1;
for (int i = 0; i < N; ++i) {
solve(argc, argv, i == 0);
}
Expand Down
64 changes: 57 additions & 7 deletions 2023/src/day23.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ const std::map<char, AbsDirection> allowed_directions{

class TrailMap {
aoc::ds::Grid<char> grid;
std::map<Pos, std::set<Pos>> grid_path;
std::map<Pos, std::set<Pos>> grid_prev;
std::map<Pos, std::set<Pos>> fwd_edges;
std::map<Pos, std::set<Pos>> undirected_edges;
std::map<std::pair<Pos, Pos>, int> distances;

bool get_grid_neighbors(const Pos &pos, const Pos &prev_pos,
Expand All @@ -54,6 +54,7 @@ class TrailMap {
explicit TrailMap(const std::vector<std::string> &grid_);
static TrailMap read(std::istream &);
int part_1() const;
int part_2() const;
};

TrailMap TrailMap::read(std::istream &is) {
Expand Down Expand Up @@ -120,8 +121,9 @@ bool TrailMap::get_grid_neighbors(const Pos &pos, const Pos &prev_pos,
}

void TrailMap::add_edge(const Pos &from, const Pos &to, int distance) {
grid_path[from].emplace(to);
grid_prev[to].emplace(from);
fwd_edges[from].emplace(to);
undirected_edges[from].emplace(to);
undirected_edges[to].emplace(from);
distances[dist_key(from, to)] = distance;
}

Expand Down Expand Up @@ -164,7 +166,7 @@ int TrailMap::part_1() const {
// find longest path in a DAG
if constexpr (aoc::DEBUG) {
std::cerr << "digraph G {\n";
for (const auto &[from, neighbors] : grid_path) {
for (const auto &[from, neighbors] : fwd_edges) {
for (const Pos &to : neighbors) {
std::cerr << " pos_" << from.x << "_" << from.y << " -> pos_"
<< to.x << "_" << to.y
Expand All @@ -179,8 +181,8 @@ int TrailMap::part_1() const {
const std::set<Pos> empty_set{};
auto get_neighbors = [this,
&empty_set](const Pos &pos) -> const std::set<Pos> & {
auto it = grid_path.find(pos);
if (it == grid_path.end()) {
auto it = fwd_edges.find(pos);
if (it == fwd_edges.end()) {
return empty_set;
}
return it->second;
Expand All @@ -201,6 +203,54 @@ int TrailMap::part_1() const {
return distance;
}

int TrailMap::part_2() const {
// try brute-force DFS?
// it runs in just over 1s on xrb in fast mode
Pos start{1, 0};
Pos target{grid.width - 2, grid.height - 1};

const std::set<Pos> empty_set{};
const auto get_neighbors =
[this, &empty_set](const Pos &pos) -> const std::set<Pos> & {
auto it = undirected_edges.find(pos);
if (it == undirected_edges.end()) {
return empty_set;
}
return it->second;
};

aoc::ds::Grid<bool> seen(grid.width, grid.height, false);
int max_distance = 0;
const auto dfs = [this, &get_neighbors, &target, &seen,
&max_distance](auto &&rec, const Pos pos, int distance,
int depth = 0) -> void {
if (pos == target) {
if (distance > max_distance) {
max_distance = distance;
}
return;
}
seen[pos] = true;
if constexpr (aoc::DEBUG) {
std::cerr << std::string(depth, ' ') << "entering " << pos << "\n";
}
for (const Pos &neighbor : get_neighbors(pos)) {
if (seen[neighbor]) {
continue;
}
rec(rec, neighbor, distance + get_distance(pos, neighbor),
depth + 1);
}
if constexpr (aoc::DEBUG) {
std::cerr << std::string(depth, ' ') << "exiting " << pos << "\n";
}
seen[pos] = false;
};

dfs(dfs, start, 0);

return max_distance;
}
} // namespace aoc::day23

#endif /* end of include guard: DAY23_HPP_VAEIOPZT */

0 comments on commit e014dac

Please sign in to comment.