#include #include #include #include #include #include "../utils.h" int xytoi (int size, int x, int y) { return size*y + x; } int itox (int size, int i) { return i % size; } int itoy (int size, int i) { return i / size; } bool oob (int sizex, int sizey, int x, int y) { if (x < 0 || y < 0) return true; if (x >= sizex || y >= sizey) return true; return false; } std::vector> get_dirs() { std::vector> dirs { { 1, 0 }, { 0, 1 }, { -1, 0 }, { 0, -1 } }; return dirs; } bool is_min (std::vector grid, int size, int i) { int x = itox(size, i); int y = itoy(size, i); for (auto dir : get_dirs()) { int j = xytoi(size, dir.first+x, dir.second+y); if (!oob(size, grid.size()/size, dir.first+x, dir.second+y)) if (grid[j] <= grid[i]) return false; } return true; } std::vector flood (std::vector grid, int size, int i) { std::vector visit ; std::vector q { i }; while (q.size() > 0) { int x = itox(size, q[0]); int y = itoy(size, q[0]); if (std::find(std::begin(visit), std::end(visit), q[0]) == std::end(visit)) visit.push_back(q[0]); q.erase(std::begin(q)); for (auto dir : get_dirs()) { int j = xytoi(size, dir.first+x, dir.second+y); if (std::find(std::begin(visit), std::end(visit), j) != std::end(visit)) continue; if (!oob(size, grid.size()/size, dir.first+x, dir.second+y)) { if (grid[j] < 9) { q.push_back(j); } } } } return visit; } int main (int argc, char * argv[]) { std::string raw; std::getline(std::ifstream(argv[1]), raw, '\0'); std::vector lines; split(lines, raw, "\n"); int size = 0; std::vector grid; for (std::string line : lines) { if (line.size() == 0) continue; size = 0; for (char c : line) { grid.push_back(std::stoi(std::string { c } )); size++; } } std::cout << "lowpoints: "; std::vector lows; int sum = 0; for (std::size_t i=0; i isles; for (auto low : lows) { auto visit = flood(grid, size, low); isles.push_back(visit.size()); } std::sort(std::begin(isles), std::end(isles), std::greater()); int res = isles[0] * isles[1] * isles[2]; std::cout << "three largest basins multiplied: " << res << std::endl; return 0; }