#pragma once #include "common.h" #include namespace aoc2021 { struct heightmap { // 0 .. 99 static const int grid = 100; static int areas[grid * grid]; struct hchar { char value = 0; char checked = 0; }; hchar hs[grid * grid]; void load(int r, line_view lv) { const char* p = lv.line; for(int i = 0; i < grid; i++) { hs[grid * r + i].value = *(p + i) - '0'; } } void low_point(int x, int y, int* d) const noexcept { char l = x == 0 ? 10 : hs[grid * y + x - 1].value; char r = x == grid - 1 ? 10 : hs[grid * y + x + 1].value; char t = y == 0 ? 10 : hs[grid * (y - 1) + x].value; char b = y == grid - 1 ? 10 : hs[grid * (y + 1) + x].value; char n = hs[grid * y + x].value; if (n < l && n < r && n < t && n < b) { *d += n + 1; } } void basin(int x, int y, int* area) { if (hs[grid * y + x].value < 9 && hs[grid * y + x].checked == 0) { *area += 1; hs[grid * y + x].checked = 1; std::pair ps[4] = {{x-1, y}, {x+1, y}, {x, y-1}, {x, y+1}}; for (auto& p : ps) { if (p.first >= 0 && p.first < grid && p.second >= 0 && p.second < grid) { basin(p.first, p.second, area); } } } } int risks() const noexcept { int r{0}; for (int y = 0; y < grid; y++) { for (int x = 0; x < grid; x++) { low_point(x, y, &r); } } return r; } int top3() { for (int y = 0; y < grid; y++) { for (int x = 0; x < grid; x++) { areas[y * grid + x] = 0; basin(x, y, &areas[y * grid + x]); } } std::sort(areas, areas + grid * grid, [](int x, int y){ return x > y;}); return areas[0] * areas[1] * areas[2]; } }; std::pair day9(line_view file); }