aoc

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

19a.c (1924B)


      1 #include <inttypes.h>
      2 #include <stdbool.h>
      3 #include <stdio.h>
      4 #include <stdlib.h>
      5 #include <string.h>
      6 
      7 #define N 1000
      8 
      9 typedef struct { int64_t val[26]; } part_t;
     10 typedef struct { char v, comp, wnext[10]; int64_t b; } rule_t;
     11 typedef struct { char name[50]; int64_t n; rule_t r[100]; } workflow_t;
     12 
     13 int64_t nw, np, A;
     14 workflow_t w[N];
     15 part_t p[N];
     16 
     17 workflow_t readw(char *buf) {
     18 	workflow_t ret = {0};
     19 	for (int i = 0; *buf != '{'; buf++, i++)
     20 		ret.name[i] = *buf;
     21 	for (rule_t r; *buf != '}'; ret.r[ret.n++] = r) {
     22 		buf++;
     23 		memset(&r, 0, sizeof(r));
     24 		if (*(buf+1) == '<' || *(buf+1) == '>') {
     25 			r.v = *buf;
     26 			r.comp = *(buf+1);
     27 			r.b = atoll(buf+2);
     28 			while (*buf != ':') buf++;
     29 			buf++;
     30 		}
     31 		for (int i = 0; *buf != ',' && *buf != '}'; buf++, i++)
     32 			r.wnext[i] = *buf;
     33 	}
     34 	return ret;
     35 }
     36 
     37 part_t readp(char *buf) {
     38 	part_t p = {0};
     39 	while (*buf != '}') {
     40 		buf++;
     41 		p.val[*buf-'a'] = atoll(buf+2);
     42 		while(*buf != ',' && *buf != '}') buf++;
     43 	}
     44 	return p;
     45 }
     46 
     47 int64_t value(part_t p) {
     48 	return p.val['x'-'a'] + p.val['m'-'a'] + p.val['a'-'a'] + p.val['s'-'a'];
     49 }
     50 
     51 bool satisfy(part_t p, rule_t r) {
     52 	if (r.v == 0) return true;
     53 	int64_t val = p.val[r.v-'a'];
     54 	return r.comp == '<' ? (val < r.b) : (val > r.b);
     55 }
     56 
     57 workflow_t findw(char *name) {
     58 	for (int i = 0; i < nw; i++)
     59 		if (!strcmp(name, w[i].name))
     60 			return w[i];
     61 	printf("Error: workflow %s not found\n", name);
     62 	exit(1);
     63 }
     64 
     65 int main() {
     66 	char *buf, line[N];
     67 
     68 	for (nw = 0; *(buf = fgets(line, N, stdin)) != '\n'; nw++)
     69 		w[nw] = readw(buf);
     70 
     71 	for (np = 0; (buf = fgets(line, N, stdin)) != NULL; np++)
     72 		p[np] = readp(buf);
     73 
     74 	for (int i = 0; i < np; i++) {
     75 		workflow_t ww = findw("in");
     76 		for (rule_t r; ; ww = findw(r.wnext)) {
     77 			for (int64_t j = 0; !satisfy(p[i], r = ww.r[j]); j++) ;
     78 			if (!strcmp("A", r.wnext) || !strcmp("R", r.wnext)) {
     79 				A += value(p[i]) * (r.wnext[0] == 'A');
     80 				break;
     81 			}
     82 		}
     83 	}
     84 
     85 	printf("%" PRId64 "\n", A);
     86 	return 0;
     87 }