aboutsummaryrefslogtreecommitdiff
path: root/2020/12/solve.c
diff options
context:
space:
mode:
authorMarvin Borner2020-12-12 15:30:32 +0100
committerMarvin Borner2020-12-12 15:30:32 +0100
commit99805b864c6c1e94946ea197b4917d9c42ed33bc (patch)
tree0954f2f54daed18fc0fc0efd373107a1a5909485 /2020/12/solve.c
parent51a1115dc9f44286c6c19d48ce5261147792e8c4 (diff)
Opened 12th door
Diffstat (limited to '2020/12/solve.c')
-rw-r--r--2020/12/solve.c145
1 files changed, 145 insertions, 0 deletions
diff --git a/2020/12/solve.c b/2020/12/solve.c
new file mode 100644
index 0000000..111f689
--- /dev/null
+++ b/2020/12/solve.c
@@ -0,0 +1,145 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+enum dir { N, E, S, W };
+
+// I <3 recursion
+enum dir rotate(enum dir dir, int cnt, int r)
+{
+ if (!cnt)
+ return dir;
+
+ if (r) { // right
+ if (dir == W)
+ dir = N;
+ else
+ dir++;
+ } else { // left
+ if (dir == N)
+ dir = W;
+ else
+ dir--;
+ }
+ return rotate(dir, cnt - 1, r);
+}
+
+// Quite inefficient but I like this approach.
+int *rotate_wp(int dirs[], int cnt, int r)
+{
+ if (!cnt)
+ return dirs;
+
+ if (r) {
+ int tmp = dirs[W];
+ dirs[W] = dirs[S];
+ dirs[S] = dirs[E];
+ dirs[E] = dirs[N];
+ dirs[N] = tmp;
+ } else {
+ int tmp = dirs[N];
+ dirs[N] = dirs[E];
+ dirs[E] = dirs[S];
+ dirs[S] = dirs[W];
+ dirs[W] = tmp;
+ }
+
+ return rotate_wp(dirs, cnt - 1, r);
+}
+
+int part_one(FILE *fp)
+{
+ char *line = NULL;
+ size_t len = 0;
+ int coords[4] = { 0 };
+ enum dir cur = E;
+ while (getline(&line, &len, fp) != -1) {
+ char dir;
+ int cnt;
+ sscanf(line, "%c%d\n", &dir, &cnt);
+ switch (dir) {
+ case 'N':
+ coords[N] += cnt;
+ break;
+ case 'E':
+ coords[E] += cnt;
+ break;
+ case 'S':
+ coords[S] += cnt;
+ break;
+ case 'W':
+ coords[W] += cnt;
+ break;
+ case 'L':
+ cur = rotate(cur, cnt / 90, 0);
+ break;
+ case 'R':
+ cur = rotate(cur, cnt / 90, 1);
+ break;
+ case 'F':
+ coords[cur] += cnt;
+ break;
+ default:
+ break;
+ }
+ }
+
+ return abs((coords[E] - coords[W]) + (coords[S] - coords[N]));
+}
+
+int part_two(FILE *fp)
+{
+ char *line = NULL;
+ size_t len = 0;
+ int wp[4] = { 1, 10, 0, 0 };
+ int coords[4] = { 0 };
+ enum dir cur = E;
+ while (getline(&line, &len, fp) != -1) {
+ char dir;
+ int cnt;
+ sscanf(line, "%c%d\n", &dir, &cnt);
+ switch (dir) {
+ case 'N':
+ wp[N] += cnt;
+ break;
+ case 'E':
+ wp[E] += cnt;
+ break;
+ case 'S':
+ wp[S] += cnt;
+ break;
+ case 'W':
+ wp[W] += cnt;
+ break;
+ case 'L':
+ rotate_wp(wp, cnt / 90, 0);
+ break;
+ case 'R':
+ rotate_wp(wp, cnt / 90, 1);
+ break;
+ case 'F':
+ coords[N] += cnt * wp[N];
+ coords[E] += cnt * wp[E];
+ coords[S] += cnt * wp[S];
+ coords[W] += cnt * wp[W];
+ break;
+ default:
+ break;
+ }
+ }
+
+ return abs((coords[E] - coords[W])) + abs((coords[S] - coords[N]));
+}
+
+int main(int argc, char *argv[])
+{
+ FILE *fp = fopen("input", "r");
+ if (!fp)
+ exit(EXIT_FAILURE);
+
+ printf("%d\n", part_one(fp));
+ rewind(fp);
+ printf("%d\n", part_two(fp));
+
+ fclose(fp);
+ return 0;
+}