summary refs log tree commit diff
diff options
context:
space:
mode:
authordzwdz2022-12-09 08:43:34 +0100
committerdzwdz2022-12-09 08:43:34 +0100
commit71e794fccb7c0a7f10ff9fb144bdffbc0fef41ad (patch)
tree257c248331d27d09dfc77be6627d493d39fbcf3d
parent4db98be450d917a9373fedb11292dd60fd81fb01 (diff)
day 9 part 1
I am aware of the better solution. I just don't care.
Another phone one btw.
-rw-r--r--22.9/main.cpp72
1 files changed, 72 insertions, 0 deletions
diff --git a/22.9/main.cpp b/22.9/main.cpp
new file mode 100644
index 0000000..46cc68e
--- /dev/null
+++ b/22.9/main.cpp
@@ -0,0 +1,72 @@
+#include <cstdio>
+#include <unordered_set>
+#include <iostream>
+using namespace std;
+
+int signum(int n) {
+	if (0 < n) return 1;
+	if (n < 0) return -1;
+	return 0;
+}
+
+struct Pos {
+	int x, y;
+
+	Pos add(Pos other) {
+		return Pos{this->x+other.x,this->y+other.y};
+	}
+	Pos sub(Pos other) {
+		return Pos{this->x-other.x,this->y-other.y};
+	}
+	
+	bool touching(Pos other) {
+		return abs(this->x - other.x) <= 1
+			&& abs(this->y - other.y) <= 1;
+	}
+
+	Pos moveTowards(Pos other) {
+		Pos p = *this;
+		if (!touching(other)) {
+			p.x += signum(other.x - this->x);
+			p.y += signum(other.y - this->y);
+		}
+		return p;
+	}
+
+	bool operator==(Pos const& p) const noexcept
+	{
+		return x == p.x && y == p.y;
+	}
+};
+
+template<>
+struct std::hash<Pos>
+{
+	size_t operator()(Pos const& p) const noexcept
+	{
+		return std::hash<int>{}(p.x) ^ (std::hash<int>{}(p.x) << 1);
+	}
+};
+
+int main() {
+	char dir;
+	int steps;
+	Pos head{0,0}, tail{0,0};
+	unordered_set<Pos> visited;
+	while (scanf("%c %d ", &dir, &steps) == 2) {
+		Pos d;
+		switch (dir) {
+			case 'R': d = {1, 0}; break;
+			case 'L': d = {-1, 0}; break;
+			case 'U': d = {0, -1}; break;
+			case 'D': d = {0, 1}; break;
+			default: throw "bad input";
+		}
+		for (int i = 0; i < steps; i++) {
+			head = head.add(d);
+			tail = tail.moveTowards(head);
+			visited.insert(tail);
+		}
+	}
+	cout << visited.size() << endl;
+}