aoc

My solutions for the Advent of Code
git clone https://git.tronto.net/aoc
Download | Log | Files | Refs | README

20a.c (1913B)


      1 #include <inttypes.h>
      2 #include <stdbool.h>
      3 #include <stdio.h>
      4 #include <string.h>
      5 
      6 #define N 100
      7 #define ischar(c) (c >= 'a' && c <= 'z')
      8 
      9 typedef struct {
     10 	int nin, nout, in[N], out[N];
     11 	char name[20], outc[N][20];
     12 	bool isff, ison, reg[N];
     13 } node_t;
     14 
     15 typedef struct {
     16 	int i, n, node[1000];
     17 	bool hi[1000];
     18 } queue_t;
     19 
     20 char *buf, line[N][N];
     21 int b, n;
     22 int64_t hitot, lowtot;
     23 node_t m[N];
     24 
     25 void add(queue_t *q, int v, bool hi) {
     26 	q->node[q->n] = v;
     27 	q->hi[q->n] = hi;
     28 	q->n++;
     29 }
     30 
     31 void send(queue_t *q, int v, bool hi) {
     32 	for (int j = 0; j < m[v].nout; j++) {
     33 		add(q, m[v].out[j], hi);
     34 		m[m[v].out[j]].reg[v] = hi;
     35 		if (hi) hitot++; else lowtot++;
     36 	}
     37 }
     38 
     39 void pushbutton(void) {
     40 	queue_t q = {0};
     41 
     42 	add(&q, b, false);
     43 	lowtot++;
     44 	while (q.i < q.n) {
     45 		int v = q.node[q.i];
     46 		bool hi = q.hi[q.i];
     47 		q.i++;
     48 
     49 		if (v == b) {
     50 			send(&q, v, hi);
     51 		} else if (m[v].isff) {
     52 			if (!hi)
     53 				send(&q, v, m[v].ison = !m[v].ison);
     54 		} else {
     55 			bool allhi = true;
     56 			for (int j = 0; j < m[v].nin; j++)
     57 				allhi = allhi && m[v].reg[m[v].in[j]];
     58 			send(&q, v, !allhi);
     59 		}
     60 	}
     61 }
     62 
     63 int main() {
     64 	for (n = 0; (buf = fgets(line[n], N, stdin)) != NULL; n++) {
     65 		if (ischar(*buf)) b = n;
     66 		m[n].isff = *buf == '%';
     67 		if (!ischar(*buf)) buf++;
     68 		for (int i = 0; ischar(*buf); m[n].name[i++] = *(buf++)) ;
     69 		buf += 4;
     70 		for (int i = 0; *buf != '\n'; i++) {
     71 			while (!ischar(*buf)) buf++;
     72 			for (int j = 0; ischar(*buf); m[n].outc[i][j++] = *(buf++)) ;
     73 		}
     74 	}
     75 
     76 	for (int i = 0; i < n; i++) {
     77 		for (int j = 0; m[i].outc[j][0]; j++) {
     78 			bool found = false;
     79 			for (int k = 0; k < n; k++) {
     80 				if (!strcmp(m[k].name, m[i].outc[j])) {
     81 					m[i].out[m[i].nout++] = k;
     82 					m[k].in[m[k].nin++] = i;
     83 					found = true;
     84 				}
     85 			}
     86 			if (!found) {
     87 				m[i].out[m[i].nout++] = n;
     88 				m[n].in[m[n].nin++] = i;
     89 				n++;
     90 			}
     91 		}
     92 	}
     93 
     94 	for (int i = 0; i < 1000; i++)
     95 		pushbutton();
     96 
     97 	printf("%" PRId64 "\n", hitot * lowtot);
     98 	return 0;
     99 }