#include #include #include #include #include #include #include #include using namespace std; using pos_type = tuple; vector read_file(string_view filename) { fstream input{ filename }; vector data; long lhs = 0; long rhs = 0; char chr = 0; while ( input >> lhs >> chr >> rhs ) { data.emplace_back(lhs, rhs); } return data; } optional bfs(const vector& data, long size) { set stones{ data.begin(), data.end() }; set seen; // x, y, distance queue> queue; queue.push({ { 0, 0 }, 0 }); while ( !queue.empty() ) { const auto& [pos, distance] = queue.front(); queue.pop(); const auto [x, y] = pos; if ( x == size && y == size ) { return distance; } if ( x < 0 || y < 0 || x > size || y > size ) { continue; } if ( stones.contains(pos) ) { continue; } if ( seen.contains(pos) ) { continue; } seen.insert(pos); for ( const auto& [nx, ny]: vector{ { x - 1, y }, { x + 1, y }, { x, y - 1 }, { x, y + 1 } } ) { queue.push({ { nx, ny }, distance + 1 }); } } return nullopt; } void part1(const vector& data, long size) { if ( auto result = bfs(data, size) ) { cout << *result << endl; } } void part2(const vector& data, long size) { for ( size_t i = 0; i != data.size(); ++i ) { const vector foo{ data.begin(), data.begin() + ptrdiff_t(i) }; if ( !bfs(foo, size) ) { const auto& [x, y] = foo.back(); cout << x << "," << y << endl; return; } } } int main() { #if 0 const auto data = read_file("data/day18-sample1.txt"); const long size = 6; part1({ data.begin(), data.begin() + 12 }, size); part2(data, size); #else const auto data = read_file("data/day18.txt"); const long size = 70; part1({ data.begin(), data.begin() + 1024 }, size); part2(data, size); #endif }