aboutsummaryrefslogtreecommitdiff
path: root/src/2019/day10/aoc.cpp
diff options
context:
space:
mode:
authorkaiwu <kaiwu2004@gmail.com>2022-12-06 17:37:52 +0800
committerkaiwu <kaiwu2004@gmail.com>2022-12-06 17:38:47 +0800
commit76183b2d789320456599ef811434f4b65cae9524 (patch)
tree7c8ff049cd7b926a99911b3cc93b40b99842d329 /src/2019/day10/aoc.cpp
parenta2807a134934bd4c831709f5271ad4ab6ef245a6 (diff)
downloadadvent-of-code-76183b2d789320456599ef811434f4b65cae9524.tar.gz
advent-of-code-76183b2d789320456599ef811434f4b65cae9524.zip
2019 day10 part2
Diffstat (limited to 'src/2019/day10/aoc.cpp')
-rw-r--r--src/2019/day10/aoc.cpp106
1 files changed, 95 insertions, 11 deletions
diff --git a/src/2019/day10/aoc.cpp b/src/2019/day10/aoc.cpp
index fbcb049..60de3ea 100644
--- a/src/2019/day10/aoc.cpp
+++ b/src/2019/day10/aoc.cpp
@@ -1,8 +1,72 @@
#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};
@@ -11,22 +75,42 @@ std::pair<int, int> day10(line_view file) {
return true;
});
- // b.print();
+ 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 observe{0};
- int max{0};
+ int max = ps[0].count;
+ belt::pos monitor = ps[0].p;
- b.iterate([&observe, &max, &b](belt::pos p){
- if (b.get(p) == '#') {
- observe = 0;
- b.count(p, &observe);
- if (observe > max) {
- max = observe;
+ 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;
}
- }
});
- return {max, 0};
+ int count{0};
+ belt::pos xp = vaporize(b, monitor, ps, &count);
+ return {max, xp.x * 100 + xp.y};
}
} // namespace aoc2019