aboutsummaryrefslogtreecommitdiff
path: root/2023/20/20a.c
blob: 1fda99e7c7827a060c778bb04a6cc81ce939878d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
#include <inttypes.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>

#define N 100
#define ischar(c) (c >= 'a' && c <= 'z')

typedef struct {
	int nin, nout, in[N], out[N];
	char name[20], outc[N][20];
	bool isff, ison, reg[N];
} node_t;

typedef struct {
	int i, n, node[1000];
	bool hi[1000];
} queue_t;

char *buf, line[N][N];
int b, n;
int64_t hitot, lowtot;
node_t m[N];

void add(queue_t *q, int v, bool hi) {
	q->node[q->n] = v;
	q->hi[q->n] = hi;
	q->n++;
}

void send(queue_t *q, int v, bool hi) {
	for (int j = 0; j < m[v].nout; j++) {
		add(q, m[v].out[j], hi);
		m[m[v].out[j]].reg[v] = hi;
		if (hi) hitot++; else lowtot++;
	}
}

void pushbutton(void) {
	queue_t q = {0};

	add(&q, b, false);
	lowtot++;
	while (q.i < q.n) {
		int v = q.node[q.i];
		bool hi = q.hi[q.i];
		q.i++;

		if (v == b) {
			send(&q, v, hi);
		} else if (m[v].isff) {
			if (!hi)
				send(&q, v, m[v].ison = !m[v].ison);
		} else {
			bool allhi = true;
			for (int j = 0; j < m[v].nin; j++)
				allhi = allhi && m[v].reg[m[v].in[j]];
			send(&q, v, !allhi);
		}
	}
}

int main() {
	for (n = 0; (buf = fgets(line[n], N, stdin)) != NULL; n++) {
		if (ischar(*buf)) b = n;
		m[n].isff = *buf == '%';
		if (!ischar(*buf)) buf++;
		for (int i = 0; ischar(*buf); m[n].name[i++] = *(buf++)) ;
		buf += 4;
		for (int i = 0; *buf != '\n'; i++) {
			while (!ischar(*buf)) buf++;
			for (int j = 0; ischar(*buf); m[n].outc[i][j++] = *(buf++)) ;
		}
	}

	for (int i = 0; i < n; i++) {
		for (int j = 0; m[i].outc[j][0]; j++) {
			bool found = false;
			for (int k = 0; k < n; k++) {
				if (!strcmp(m[k].name, m[i].outc[j])) {
					m[i].out[m[i].nout++] = k;
					m[k].in[m[k].nin++] = i;
					found = true;
				}
			}
			if (!found) {
				m[i].out[m[i].nout++] = n;
				m[n].in[m[n].nin++] = i;
				n++;
			}
		}
	}

	for (int i = 0; i < 1000; i++)
		pushbutton();

	printf("%" PRId64 "\n", hitot * lowtot);
	return 0;
}

Generated with cgit - Back to sebastiano.tronto.net