#include "aoc.h" #include #include #include namespace aoc2019 { struct posd { belt::pos p; belt::distance d; int count = 0; }; float angle(int x, int y) { auto a = atan2(y, x); auto r = a * 180 / M_PI; if (r > 360) { r -= 360; } if (r < 0) { r += 360; } r += 90; return r >= 360 ? r - 360 : r; } belt::pos vaporize(belt b, belt::pos& m, std::vector& ps, int* count) { belt bx = b; for (auto& dp : ps) { if (dp.count == 0 && !bx.blocked(dp.p, m)) { dp.count = 1; b.get(dp.p) = '.'; *count += 1; // printf("%d asteroid to be vaporized is at (%d, %d)\n", *count, dp.p.x, dp.p.y); if (*count == 200) { return dp.p; } } } return vaporize(b, m, ps, count); } std::pair day10(line_view file) { belt b; int r{0}; per_line(file, [&b, &r](line_view lv) { b.load(lv, r++); return true; }); std::vector ps; b.iterate([&ps, &b](belt::pos p){ if (b.get(p) == '#') { posd d; d.p = p; b.count(p, &d.count); ps.push_back(d); } }); std::sort(ps.begin(), ps.end(), [](const posd& d1, const posd& d2){ return d1.count > d2.count; }); int max = ps[0].count; belt::pos monitor = ps[0].p; for (auto& a : ps) { a.d = b.dist(a.p, monitor); a.count = a.p == monitor ? 1 : 0; // mark as not lazered } std::sort(ps.begin(), ps.end(), [](const posd& d1, const posd& d2) { return angle(d1.d.dx, d1.d.dy) < angle(d2.d.dx, d2.d.dy); }); int count{0}; belt::pos xp = vaporize(b, monitor, ps, &count); return {max, xp.x * 100 + xp.y}; } } // namespace aoc2019