aboutsummaryrefslogtreecommitdiff
path: root/src/2017/day22/aoc.cpp
diff options
context:
space:
mode:
authorkaiwu <kaiwu2004@gmail.com>2023-03-09 17:01:33 +0800
committerkaiwu <kaiwu2004@gmail.com>2023-03-09 17:01:33 +0800
commit032241952fd7afb297b579d6c1914dbd035e8060 (patch)
tree1b772d1a62068f98b0d4069c84af23cfbf31bbbe /src/2017/day22/aoc.cpp
parent735159661c0684a6aec4323150238c84fc4a7020 (diff)
downloadadvent-of-code-032241952fd7afb297b579d6c1914dbd035e8060.tar.gz
advent-of-code-032241952fd7afb297b579d6c1914dbd035e8060.zip
2017 day22 part1
Diffstat (limited to 'src/2017/day22/aoc.cpp')
-rw-r--r--src/2017/day22/aoc.cpp90
1 files changed, 89 insertions, 1 deletions
diff --git a/src/2017/day22/aoc.cpp b/src/2017/day22/aoc.cpp
index b2e2dfb..3e9a907 100644
--- a/src/2017/day22/aoc.cpp
+++ b/src/2017/day22/aoc.cpp
@@ -1,6 +1,94 @@
#include "aoc.h"
+#include <set>
namespace aoc2017 {
-std::pair<int64_t, int64_t> day22(line_view) { return {0, 0}; }
+static int radias = 12; // demo 25/2 = 12 input
+enum facing {
+ f_up,
+ f_down,
+ f_right,
+ f_left,
+};
+
+struct vpos {
+ int x;
+ int y;
+ facing f;
+};
+
+static vpos turn_right(vpos p) {
+ facing fs[4] = {f_right, f_left, f_down, f_up};
+ return {p.x, p.y, fs[(int)p.f]};
+}
+
+static vpos turn_left(vpos p) {
+ facing fs[4] = {f_left, f_right, f_up, f_down};
+ return {p.x, p.y, fs[(int)p.f]};
+}
+
+static vpos move(vpos p) {
+ vpos vs[4] = {
+ {p.x, p.y - 1, p.f},
+ {p.x, p.y + 1, p.f},
+ {p.x + 1, p.y, p.f},
+ {p.x - 1, p.y, p.f},
+ };
+ return vs[(int)p.f];
+}
+
+vpos burst(std::set<node22>& infected, vpos p, int* c) {
+ auto it = infected.find({p.x, p.y});
+ bool is_infected = it != infected.end();
+ // If the current node is infected, it turns to its right. Otherwise, it turns to its left. (Turning is done in-place;
+ // the current node does not change.)
+ vpos px = is_infected ? turn_right(p) : turn_left(p);
+
+ // If the current node is clean, it becomes infected. Otherwise, it becomes
+ // cleaned. (This is done after the node is considered for the purposes of changing direction.) The virus carrier
+ if (!is_infected) {
+ infected.insert({p.x, p.y});
+ *c += 1;
+ } else {
+ infected.erase(it);
+ }
+
+ // moves forward one node in the direction it is facing.
+ px = move(px);
+ return px;
+}
+
+static void load(std::set<node22>& is, int r, line_view lv) {
+ const char* p = lv.line;
+ int x = 0;
+ while (*(p + x) != '\n') {
+ if (*(p + x) == '#') {
+ node22 n{x - radias, r - radias};
+ is.insert(n);
+ }
+ x++;
+ }
+}
+
+std::pair<int64_t, int64_t> day22(line_view file) {
+ std::set<node22> infected;
+
+ int r{0};
+ per_line(file, [&r, &infected](line_view lv) {
+ load(infected, r++, lv);
+ return true;
+ });
+
+ vpos p{0, 0, f_up};
+ int t0{0};
+ for (int i = 0; i < 10000; i++) {
+ p = burst(infected, p, &t0);
+ }
+
+ // for (auto& n : infected) {
+ // printf("%d,%d\n", n.x, n.y);
+ // }
+ return {t0, 0};
+}
+
} // namespace aoc2017