aboutsummaryrefslogtreecommitdiff
path: root/2023/20/20b.c
diff options
context:
space:
mode:
Diffstat (limited to '2023/20/20b.c')
-rw-r--r--2023/20/20b.c143
1 files changed, 143 insertions, 0 deletions
diff --git a/2023/20/20b.c b/2023/20/20b.c
new file mode 100644
index 0000000..dc0d6b3
--- /dev/null
+++ b/2023/20/20b.c
@@ -0,0 +1,143 @@
1/*
2This one is a bit weird. This program works only for my specific input
3(included in this folder). Similarly to number 8, this program outputs
44 numbers and you have to take the lcm of them.
5
6I solved it this way:
71. First, using a modified version of the code for part one (graph.c),
8 I printed the graph as a list of adjacency lists.
92. I then went to https://csacademy.com/app/graph_editor and observed
10 the graph. I noticed that after the button is pressed, the signal
11 is sent to 4 independent parts of the graph. Each of these parts has
12 only one entry point and one exit point. The entry points were not
13 flip-flop nodes.
143. Finally, I implemented the code to check how long it takes for the
15 graph to go back to the initial state, and I simulated sending a
16 signal to each of the 4 parts independently.
17*/
18
19#include <inttypes.h>
20#include <stdbool.h>
21#include <stdio.h>
22#include <stdlib.h>
23#include <string.h>
24
25#define N 100
26#define ischar(c) (c >= 'a' && c <= 'z')
27
28typedef struct {
29 int nin, nout, in[N], out[N];
30 char name[20], outc[N][20];
31 bool isff, ison, reg[N];
32} node_t;
33
34typedef struct {
35 int i, n;
36 struct {int node; bool hi;} elem[500];
37} queue_t;
38
39char *buf, line[N][N];
40bool rx;
41int b, r, n;
42node_t m[N];
43queue_t q;
44
45void add(int v, bool hi) {
46 q.elem[q.n].node = v;
47 q.elem[q.n].hi = hi;
48 q.n++;
49}
50
51void send(int v, bool hi) {
52 for (int j = 0; j < m[v].nout; j++) {
53 add(m[v].out[j], hi);
54 m[m[v].out[j]].reg[v] = hi;
55 }
56}
57
58int findm(char *name) {
59 for (int k = 0; k < n; k++)
60 if (!strcmp(m[k].name, name))
61 return k;
62 return n;
63}
64
65void sig(int node, bool high) {
66 q.n = q.i = 0;
67 add(node, high);
68 while (q.i < q.n) {
69 int v = q.elem[q.i].node;
70 bool hi = q.elem[q.i].hi;
71 q.i++;
72
73 if (v == b) {
74 send(v, hi);
75 } else if (m[v].isff) {
76 if (!hi)
77 send(v, m[v].ison = !m[v].ison);
78 } else {
79 bool allhi = true;
80 for (int j = 0; j < m[v].nin; j++)
81 allhi = allhi && m[v].reg[m[v].in[j]];
82 send(v, !allhi);
83 }
84 }
85}
86
87bool isclean(void) {
88 for (int i = 0; i < n; i++) {
89 if (m[i].isff && m[i].ison)
90 return false;
91 else
92 for (int j = 0; j < m[i].nin; j++)
93 if (m[i].reg[j])
94 return false;
95 }
96 return true;
97}
98
99int64_t period(int node) {
100 int64_t npush = 0;
101 do {
102 sig(node, false);
103 npush++;
104 } while (!isclean());
105 return npush;
106}
107
108int main() {
109 for (n = 0; (buf = fgets(line[n], N, stdin)) != NULL; n++) {
110 if (ischar(*buf)) b = n;
111 m[n].isff = *buf == '%';
112 if (!ischar(*buf)) buf++;
113 for (int i = 0; ischar(*buf); m[n].name[i++] = *(buf++)) ;
114 buf += 4;
115 for (int i = 0; *buf != '\n'; i++) {
116 while (!ischar(*buf)) buf++;
117 for (int j = 0; ischar(*buf); m[n].outc[i][j++] = *(buf++)) ;
118 }
119 }
120
121 for (int i = 0; i < n; i++) {
122 for (int j = 0; m[i].outc[j][0]; j++) {
123 int k = findm(m[i].outc[j]);
124 m[i].out[m[i].nout++] = k;
125 m[k].in[m[k].nin++] = i;
126 if (k == n) {
127 for (int k = 0; m[i].outc[j][k]; k++)
128 m[n].name[k] = m[i].outc[j][k];
129 n++;
130 }
131 }
132 }
133
134 for (int i = 0; i < n; i++)
135 if (!strcmp(m[i].name, "rx"))
136 r = i;
137
138 printf("%" PRId64 "\n", period(19));
139 printf("%" PRId64 "\n", period(33));
140 printf("%" PRId64 "\n", period(39));
141 printf("%" PRId64 "\n", period(57));
142 return 0;
143}

Generated with cgit - Back to sebastiano.tronto.net