summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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;
+}