diff options
author | Marvin Borner | 2020-12-12 15:30:32 +0100 |
---|---|---|
committer | Marvin Borner | 2020-12-12 15:30:32 +0100 |
commit | 99805b864c6c1e94946ea197b4917d9c42ed33bc (patch) | |
tree | 0954f2f54daed18fc0fc0efd373107a1a5909485 /2020/12/solve.c | |
parent | 51a1115dc9f44286c6c19d48ce5261147792e8c4 (diff) |
Opened 12th door
Diffstat (limited to '2020/12/solve.c')
-rw-r--r-- | 2020/12/solve.c | 145 |
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; +} |