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
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
|
#include "aoc.h"
#include <algorithm>
#include <vector>
namespace aoc2019 {
struct posd {
belt::pos p;
belt::distance d;
int count = 0;
};
enum dim {
xe0yl0,
xg0yl0,
xg0ye0,
xg0yg0,
xe0yg0,
xl0yg0,
xl0ye0,
xl0yl0
};
dim dimention(belt::distance d) {
if (d.dx == 0 && d.dy < 0) return xe0yl0;
if (d.dx > 0 && d.dy < 0) return xg0yl0;
if (d.dx > 0 && d.dy == 0) return xg0ye0;
if (d.dx > 0 && d.dy > 0) return xg0yg0;
if (d.dx == 0 && d.dy > 0) return xe0yg0;
if (d.dx < 0 && d.dy > 0) return xl0yg0;
if (d.dx < 0 && d.dy == 0) return xl0ye0;
return xl0yl0;
}
bool dimcmp(dim m, belt::distance d1, belt::distance d2) {
int x1 = std::abs(d1.dx);
int y1 = std::abs(d1.dy);
int x2 = std::abs(d2.dx);
int y2 = std::abs(d2.dy);
switch (m) {
case xe0yl0: return y1 < y2;
case xg0yl0: return y1 > y2 ? true : y1 < y2 ? false : x1 < x2;
case xg0ye0: return x1 < x2;
case xg0yg0: return y1 < y2 ? true : y1 > y2 ? false : x1 < x2;
case xe0yg0: return y1 < y2;
case xl0yg0: return y1 > y2 ? true : y1 < y2 ? false : x1 < x2;
case xl0ye0: return x1 < x2;
case xl0yl0: return y1 < y2 ? true : y1 > y2 ? false : x1 < x2;
}
return false;
}
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) {
dim m1 = dimention(d1.d);
dim m2 = dimention(d2.d);
if (m1 == m2) {
return dimcmp(m1, d1.d, d2.d);
}
else {
return (int) m1 < (int) m2;
}
});
int count{0};
belt::pos xp = vaporize(b, monitor, ps, &count);
return {max, xp.x * 100 + xp.y};
}
} // namespace aoc2019
|