aboutsummaryrefslogtreecommitdiff
path: root/2023/08/8b.c
diff options
context:
space:
mode:
Diffstat (limited to '2023/08/8b.c')
-rw-r--r--2023/08/8b.c96
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/*
2I hate this stupid problem. If you read the description carefully (which is
3what I did), you would think that the problem is much, much harder than it
4actually is. In reality, the author made many assumptions about the possible
5paths 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
18Fuck.
19
20This code does not even solve the problem by the way, it computes some data
21about the path that each ghost takes. Then you can figure out the solution
22with 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
33typedef struct { char last; int next[2]; } node_t;
34typedef struct { int preplen, plen, nz, z[N], zid[N]; } source_t;
35
36int 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
44int v[N*N];
45source_t worksource(int i, node_t *nodes, char *dir, int n, int k) {
46 source_t s;
47 int state;
48
49printf("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;
55if (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];
59printf("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
67int 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
89printf("%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}

Generated with cgit - Back to sebastiano.tronto.net