diff options
Diffstat (limited to 'src/2022/day15/aoc.cpp')
-rw-r--r-- | src/2022/day15/aoc.cpp | 56 |
1 files changed, 38 insertions, 18 deletions
diff --git a/src/2022/day15/aoc.cpp b/src/2022/day15/aoc.cpp index 0196a11..52237dd 100644 --- a/src/2022/day15/aoc.cpp +++ b/src/2022/day15/aoc.cpp @@ -2,12 +2,13 @@ #include <algorithm> namespace aoc2022 { -int sensor::minx; -int sensor::maxx; - typedef sensor::pos pos; typedef sensor::line line; +int sensor::minx; +int sensor::maxx; +std::set<pos> sensor::beacons; + static std::vector<line> merge(const std::vector<line>& ls) { std::vector<line> merged; if (ls.empty()) @@ -16,7 +17,7 @@ static std::vector<line> merge(const std::vector<line>& ls) { merged.push_back(ls[0]); for (size_t i = 1; i < ls.size(); i++) { line& last = merged[merged.size() - 1]; - if (last.p1.x >= ls[i].p0.x) { + if (last.p1.x + 1 >= ls[i].p0.x) { last.p1.x = ls[i].p1.x; } else { merged.push_back(ls[i]); @@ -38,13 +39,17 @@ int no_beacon(int y, std::vector<sensor>& ss) { int x = sensor::minx; while (x <= sensor::maxx) { pos p{x, y}; - for (auto& s : ss) { - if (s.inscope(p)) { - int d = sensor::mdistance(s.ps[0], s.ps[1]); - int dy = y - s.ps[0].y; - auto x0 = x + 2 * (d - std::abs(dy)); + for (size_t i = 0; i < ss.size(); i++) { + auto& s = ss[i]; + auto d1 = sensor::mdistance(s.ps[0], s.ps[1]); + auto d2 = sensor::mdistance(s.ps[0], p); + if (d2 <= d1) { + auto dy = s.ps[0].y - y; + auto x0 = s.ps[0].x + d2 - std::abs(dy); if (p == s.ps[1]) { ls.push_back({{x + 1, y}, {x0, y}}); + } else if (pos{x0, y} == s.ps[1]) { + ls.push_back({{x, y}, {x0 - 1, y}}); } else { ls.push_back({{x, y}, {x0, y}}); } @@ -61,16 +66,28 @@ int no_beacon(int y, std::vector<sensor>& ss) { size_t one_beacon(int range, std::vector<sensor>& ss) { for (int y = 0; y <= range; y++) { + if (y % 10000 == 0) { + printf("%d\n", y); + } std::vector<line> ls; int x = 0; while (x <= range) { pos p{x, y}; - for (auto& s : ss) { - if (s.inscope(p)) { - int d = sensor::mdistance(s.ps[0], s.ps[1]); - int dy = y - s.ps[0].y; - ls.push_back(s.line_by_dy(dy)); - x += 2 * (d - std::abs(dy)); + for (size_t i = 0; i < ss.size(); i++) { + auto& s = ss[i]; + auto d1 = sensor::mdistance(s.ps[0], s.ps[1]); + auto d2 = sensor::mdistance(s.ps[0], p); + if (d2 <= d1) { + auto dy = s.ps[0].y - y; + auto x0 = s.ps[0].x + d2 - std::abs(dy); + if (p == s.ps[1]) { + ls.push_back({{x + 1, y}, {x0, y}}); + } else if (pos{x0, y} == s.ps[1]) { + ls.push_back({{x, y}, {x0 - 1, y}}); + } else { + ls.push_back({{x, y}, {x0, y}}); + } + x = x0; break; } } @@ -79,7 +96,11 @@ size_t one_beacon(int range, std::vector<sensor>& ss) { std::sort(ls.begin(), ls.end()); auto m = merge(ls); if (m.size() > 1) { - printf("%d, %d\n", m[0].p1.x + 1, y); + pos p{m[0].p1.x+1, y}; + if (sensor::beacons.find(p) == sensor::beacons.end()) { + printf("%d %d\n", m[0].p1.x+1, y); + return ((size_t) m[0].p1.x+1) * range + y; + } } } return 0; @@ -93,8 +114,7 @@ std::pair<int, int> day15(line_view file) { }); std::sort(ss.begin(), ss.end()); auto n1 = no_beacon(2000000, ss); - // auto n2 = one_beacon(4000000, ss); - auto n2 = one_beacon(20, ss); + auto n2 = one_beacon(4000000, ss); return {n1, n2}; } |