diff options
| author | Sebastiano Tronto <sebastiano@tronto.net> | 2023-12-25 17:56:34 +0100 |
|---|---|---|
| committer | Sebastiano Tronto <sebastiano@tronto.net> | 2023-12-25 17:56:34 +0100 |
| commit | 94d0033ed89bb5bfb6500051296892fb7cea6c29 (patch) | |
| tree | 245eac2218310c958c2df2fad5109ea4f7b2a9d9 /2023/08/8b.c | |
| parent | 6a480c4eb9c96c82a8fd3663f0fbee4d32e56f19 (diff) | |
| download | aoc-94d0033ed89bb5bfb6500051296892fb7cea6c29.tar.gz aoc-94d0033ed89bb5bfb6500051296892fb7cea6c29.zip | |
Small cleanup
Diffstat (limited to '2023/08/8b.c')
| -rw-r--r-- | 2023/08/8b.c | 70 |
1 files changed, 22 insertions, 48 deletions
diff --git a/2023/08/8b.c b/2023/08/8b.c index 713bada..f704a36 100644 --- a/2023/08/8b.c +++ b/2023/08/8b.c | |||
| @@ -1,74 +1,50 @@ | |||
| 1 | /* | 1 | /* |
| 2 | I hate this stupid problem. If you read the description carefully (which is | 2 | I hate this stupid problem. There are a bunch of unwritten properties |
| 3 | what I did), you would think that the problem is much, much harder than it | 3 | of the paths that make the problem very simple: |
| 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 | 4 | ||
| 7 | - Different ghost's path do not end up in the same Z-node (this is not super | 5 | - Different ghosts' paths do not end up in the same Z-node. |
| 8 | important for the solution). | 6 | - Each ghost has exactly one Z-node in its path. |
| 9 | - Each ghost has exactly one Z-node in its path (one could think about this | 7 | - Each ghost meets a Z-node exactly once before entering a loop. |
| 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 | 8 | - 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? | 9 | every X steps; preperiods just end up aligning nicely. |
| 16 | what is this, a problem for babies?) | ||
| 17 | 10 | ||
| 18 | Fuck. | 11 | In practice, everything just works out so that the lcm of the periods |
| 19 | 12 | is the solution, which is very much not the case for a general input. | |
| 20 | This code does not even solve the problem by the way, it computes some data | 13 | This code computes the periods of the paths of the different ghosts. Then |
| 21 | about the path that each ghost takes. Then you can figure out the solution | 14 | you can figure out the solution with a pocket calculator, or by hand. |
| 22 | with a pocket calculator, or by hand. | ||
| 23 | */ | 15 | */ |
| 24 | #include <inttypes.h> | 16 | |
| 25 | #include <math.h> | ||
| 26 | #include <stdbool.h> | ||
| 27 | #include <stdio.h> | 17 | #include <stdio.h> |
| 28 | #include <stdlib.h> | ||
| 29 | #include <string.h> | 18 | #include <string.h> |
| 30 | 19 | ||
| 31 | #define N 1000 | 20 | #define N 1000 |
| 32 | 21 | ||
| 33 | typedef struct { char last; int next[2]; } node_t; | 22 | typedef struct { char last; int next[2]; } node_t; |
| 34 | typedef struct { int preplen, plen, nz, z[N], zid[N]; } source_t; | 23 | |
| 24 | int v[N*N]; | ||
| 35 | 25 | ||
| 36 | int ind(char s[3], char m[][3], int n) { | 26 | int ind(char s[3], char m[][3], int n) { |
| 37 | for (int j = 0; j < n; j++) | 27 | for (int j = 0; j < n; j++) |
| 38 | if (s[0] == m[j][0] && s[1] == m[j][1] && s[2] == m[j][2]) | 28 | if (s[0] == m[j][0] && s[1] == m[j][1] && s[2] == m[j][2]) |
| 39 | return j; | 29 | return j; |
| 40 | |||
| 41 | return -1; | 30 | return -1; |
| 42 | } | 31 | } |
| 43 | 32 | ||
| 44 | int v[N*N]; | 33 | int findperiod(int i, node_t *nodes, char *dir, int n, int k) { |
| 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); | 34 | memset(v, 0, sizeof(int) * N*N); |
| 52 | for (int j = i, d = 0, l = 1; true; d = (d+1)%k) { | 35 | for (int j = i, d = 0, l = 1, state = -1; ; d = (d+1)%k) { |
| 53 | j = nodes[j].next[dir[d] == 'R']; | 36 | j = nodes[j].next[dir[d] == 'R']; |
| 54 | state = j*k+d; | 37 | state = j*k+d; |
| 55 | if (nodes[j].last == 'Z') printf("Found Z %d at %d\n", j, l); | 38 | if (v[state]) return l - v[state]; |
| 56 | if (v[state]) { | 39 | else v[state] = l++; |
| 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 | } | 40 | } |
| 63 | 41 | return -1; | |
| 64 | return s; | ||
| 65 | } | 42 | } |
| 66 | 43 | ||
| 67 | int main() { | 44 | int main() { |
| 68 | node_t nodes[N]; | 45 | 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]; | 46 | char *buf, dir[N], line[N], name[N][3], lstr[N][3], rstr[N][3]; |
| 71 | int k, i, n, m, s; | 47 | int k, n; |
| 72 | 48 | ||
| 73 | k = strlen(fgets(dir, N, stdin)) - 1; | 49 | k = strlen(fgets(dir, N, stdin)) - 1; |
| 74 | fgets(line, N, stdin); | 50 | fgets(line, N, stdin); |
| @@ -81,16 +57,14 @@ int main() { | |||
| 81 | memcpy(rstr[n], buf+1, 3); | 57 | memcpy(rstr[n], buf+1, 3); |
| 82 | } | 58 | } |
| 83 | 59 | ||
| 84 | for (i = 0; i < n; i++) { | 60 | for (int i = 0; i < n; i++) { |
| 85 | nodes[i].next[0] = ind(lstr[i], name, n); | 61 | nodes[i].next[0] = ind(lstr[i], name, n); |
| 86 | nodes[i].next[1] = ind(rstr[i], name, n); | 62 | nodes[i].next[1] = ind(rstr[i], name, n); |
| 87 | } | 63 | } |
| 88 | 64 | ||
| 89 | printf("%d %d\n", n, k); | 65 | for (int i = 0; i < n; i++) |
| 90 | |||
| 91 | for (i = 0, m = 0; i < n; i++) | ||
| 92 | if (nodes[i].last == 'A') | 66 | if (nodes[i].last == 'A') |
| 93 | src[m++] = worksource(i, nodes, dir, n, k); | 67 | printf("%d\n", findperiod(i, nodes, dir, n, k)); |
| 94 | 68 | ||
| 95 | return 0; | 69 | return 0; |
| 96 | } | 70 | } |
