diff options
Diffstat (limited to '2023/08/8b.c')
| -rw-r--r-- | 2023/08/8b.c | 96 |
1 files changed, 96 insertions, 0 deletions
diff --git a/2023/08/8b.c b/2023/08/8b.c new file mode 100644 index 0000000..713bada --- /dev/null +++ b/2023/08/8b.c | |||
| @@ -0,0 +1,96 @@ | |||
| 1 | /* | ||
| 2 | I hate this stupid problem. If you read the description carefully (which is | ||
| 3 | what I did), you would think that the problem is much, much harder than it | ||
| 4 | actually is. In reality, the author made many assumptions about the possible | ||
| 5 | paths that made is super easy. Let's see a few: | ||
| 6 | |||
| 7 | - Different ghost's path do not end up in the same Z-node (this is not super | ||
| 8 | important for the solution). | ||
| 9 | - Each ghost has exactly one Z-node in its path (one could think about this | ||
| 10 | when reading the strange remark that "there are as many A-nodes as Z-nodes", | ||
| 11 | which does not look important at first). | ||
| 12 | - Each ghosts meets a Z-node exactly once before entering a loop (this is | ||
| 13 | a fundamental and incredibly strong assupmtion). | ||
| 14 | - If a ghost encounters a Z-node after X steps, it will encounter it exactly | ||
| 15 | every X steps (like WTF I don't even have to solve a system of congruences? | ||
| 16 | what is this, a problem for babies?) | ||
| 17 | |||
| 18 | Fuck. | ||
| 19 | |||
| 20 | This code does not even solve the problem by the way, it computes some data | ||
| 21 | about the path that each ghost takes. Then you can figure out the solution | ||
| 22 | with a pocket calculator, or by hand. | ||
| 23 | */ | ||
| 24 | #include <inttypes.h> | ||
| 25 | #include <math.h> | ||
| 26 | #include <stdbool.h> | ||
| 27 | #include <stdio.h> | ||
| 28 | #include <stdlib.h> | ||
| 29 | #include <string.h> | ||
| 30 | |||
| 31 | #define N 1000 | ||
| 32 | |||
| 33 | typedef struct { char last; int next[2]; } node_t; | ||
| 34 | typedef struct { int preplen, plen, nz, z[N], zid[N]; } source_t; | ||
| 35 | |||
| 36 | int ind(char s[3], char m[][3], int n) { | ||
| 37 | for (int j = 0; j < n; j++) | ||
| 38 | if (s[0] == m[j][0] && s[1] == m[j][1] && s[2] == m[j][2]) | ||
| 39 | return j; | ||
| 40 | |||
| 41 | return -1; | ||
| 42 | } | ||
| 43 | |||
| 44 | int v[N*N]; | ||
| 45 | source_t worksource(int i, node_t *nodes, char *dir, int n, int k) { | ||
| 46 | source_t s; | ||
| 47 | int state; | ||
| 48 | |||
| 49 | printf("Working source %d\n", i); | ||
| 50 | |||
| 51 | memset(v, 0, sizeof(int) * N*N); | ||
| 52 | for (int j = i, d = 0, l = 1; true; d = (d+1)%k) { | ||
| 53 | j = nodes[j].next[dir[d] == 'R']; | ||
| 54 | state = j*k+d; | ||
| 55 | if (nodes[j].last == 'Z') printf("Found Z %d at %d\n", j, l); | ||
| 56 | if (v[state]) { | ||
| 57 | s.preplen = v[state]-1; | ||
| 58 | s.plen = l - v[state]; | ||
| 59 | printf("Stopping at %d. Preperiod: %d, period: %d\n", l, s.preplen, s.plen); | ||
| 60 | return s; | ||
| 61 | } else v[state] = l++; | ||
| 62 | } | ||
| 63 | |||
| 64 | return s; | ||
| 65 | } | ||
| 66 | |||
| 67 | int main() { | ||
| 68 | node_t nodes[N]; | ||
| 69 | source_t src[N]; | ||
| 70 | char *buf, dir[N], line[N], name[N][3], lstr[N][3], rstr[N][3]; | ||
| 71 | int k, i, n, m, s; | ||
| 72 | |||
| 73 | k = strlen(fgets(dir, N, stdin)) - 1; | ||
| 74 | fgets(line, N, stdin); | ||
| 75 | for (n = 0; (buf = fgets(line, N, stdin)) != NULL; n++) { | ||
| 76 | memcpy(name[n], buf, 3); | ||
| 77 | nodes[n].last = name[n][2]; | ||
| 78 | while (*buf != '(') buf++; | ||
| 79 | memcpy(lstr[n], buf+1, 3); | ||
| 80 | while (*buf != ' ') buf++; | ||
| 81 | memcpy(rstr[n], buf+1, 3); | ||
| 82 | } | ||
| 83 | |||
| 84 | for (i = 0; i < n; i++) { | ||
| 85 | nodes[i].next[0] = ind(lstr[i], name, n); | ||
| 86 | nodes[i].next[1] = ind(rstr[i], name, n); | ||
| 87 | } | ||
| 88 | |||
| 89 | printf("%d %d\n", n, k); | ||
| 90 | |||
| 91 | for (i = 0, m = 0; i < n; i++) | ||
| 92 | if (nodes[i].last == 'A') | ||
| 93 | src[m++] = worksource(i, nodes, dir, n, k); | ||
| 94 | |||
| 95 | return 0; | ||
| 96 | } | ||
