1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
|
#include "aoc.h"
#include <algorithm>
#include <vector>
#include <math.h>
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<posd>& 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<int, int> 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<posd> 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
|