aboutsummaryrefslogtreecommitdiff
path: root/2023/19
diff options
context:
space:
mode:
authorSebastiano Tronto <sebastiano@tronto.net>2023-12-19 15:54:12 +0100
committerSebastiano Tronto <sebastiano@tronto.net>2023-12-19 15:54:12 +0100
commit1f75d7c9ebec207c8193754792076dc66eba9713 (patch)
tree48556a419f050153513cd5a3b8a4a6e125ba2c45 /2023/19
parent83adb5e4215a25d17cfc11b4dbf10cf20c418c20 (diff)
downloadaoc-1f75d7c9ebec207c8193754792076dc66eba9713.tar.gz
aoc-1f75d7c9ebec207c8193754792076dc66eba9713.zip
Added solutions for 15, 16, 17, 18 and 19
Diffstat (limited to '2023/19')
-rw-r--r--2023/19/19a.c87
-rw-r--r--2023/19/19b.c98
2 files changed, 185 insertions, 0 deletions
diff --git a/2023/19/19a.c b/2023/19/19a.c
new file mode 100644
index 0000000..81ee535
--- /dev/null
+++ b/2023/19/19a.c
@@ -0,0 +1,87 @@
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
9typedef struct { int64_t val[26]; } part_t;
10typedef struct { char v, comp, wnext[10]; int64_t b; } rule_t;
11typedef struct { char name[50]; int64_t n; rule_t r[100]; } workflow_t;
12
13int64_t nw, np, A;
14workflow_t w[N];
15part_t p[N];
16
17workflow_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
37part_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
47int64_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
51bool 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
57workflow_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
65int 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}
diff --git a/2023/19/19b.c b/2023/19/19b.c
new file mode 100644
index 0000000..c7cecb6
--- /dev/null
+++ b/2023/19/19b.c
@@ -0,0 +1,98 @@
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#define MAX(x,y) ((x)>(y)?(x):(y))
9
10typedef struct { int64_t val[26]; } part_t;
11typedef struct { char v, comp, wnext[10]; int64_t b; } rule_t;
12typedef struct { char name[50]; int64_t n; rule_t r[100]; } workflow_t;
13
14int64_t nw, A;
15workflow_t w[N];
16part_t p[N];
17
18workflow_t readw(char *buf) {
19 workflow_t ret = {0};
20 for (int i = 0; *buf != '{'; buf++, i++)
21 ret.name[i] = *buf;
22 for (rule_t r; *buf != '}'; ret.r[ret.n++] = r) {
23 buf++;
24 memset(&r, 0, sizeof(r));
25 if (*(buf+1) == '<' || *(buf+1) == '>') {
26 r.v = *buf;
27 r.comp = *(buf+1);
28 r.b = atoll(buf+2);
29 while (*buf != ':') buf++;
30 buf++;
31 }
32 for (int i = 0; *buf != ',' && *buf != '}'; buf++, i++)
33 r.wnext[i] = *buf;
34 }
35 return ret;
36}
37
38workflow_t findw(char *name) {
39 for (int i = 0; i < nw; i++)
40 if (!strcmp(name, w[i].name))
41 return w[i];
42 printf("Error: workflow %s not found\n", name);
43 exit(1);
44}
45
46int64_t work(workflow_t ww, int64_t lox, int64_t hix, int64_t lom, int64_t him,
47 int64_t loa, int64_t hia, int64_t los, int64_t his) {
48 if (lox > hix || lom > him || loa > hia || los > his)
49 return 0;
50
51 int64_t ret = 0;
52 for (int j = 0; j < ww.n; j++) {
53 int64_t lox1 = lox, hix1 = hix, lom1 = lom, him1 = him,
54 loa1 = loa, hia1 = hia, los1 = los, his1 = his;
55 rule_t r = ww.r[j];
56 switch (r.v) {
57 case 'x':
58 if (r.comp == '<') { hix1 = r.b-1; lox = r.b; }
59 else { lox1 = r.b+1, hix = r.b; }
60 break;
61 case 'm':
62 if (r.comp == '<') { him1 = r.b-1; lom = r.b; }
63 else { lom1 = r.b+1, him = r.b; }
64 break;
65 case 'a':
66 if (r.comp == '<') { hia1 = r.b-1; loa = r.b; }
67 else { loa1 = r.b+1, hia = r.b; }
68 break;
69 case 's':
70 if (r.comp == '<') { his1 = r.b-1; los = r.b; }
71 else { los1 = r.b+1, his = r.b; }
72 break;
73 default:
74 break;
75 }
76 ret += (r.wnext[0] == 'A' || r.wnext[0] == 'R') ?
77 MAX(0, hix1-lox1+1) * MAX(0, him1-lom1+1) *
78 MAX(0, hia1-loa1+1) * MAX(0, his1-los1+1) *
79 (r.wnext[0] == 'A')
80 :
81 work(findw(r.wnext), lox1, hix1,
82 lom1, him1, loa1, hia1, los1, his1);
83 }
84
85 return ret;
86}
87
88int main() {
89 char *buf, line[N];
90
91 for (nw = 0; *(buf = fgets(line, N, stdin)) != '\n'; nw++)
92 w[nw] = readw(buf);
93
94 int64_t s = work(findw("in"), 1, 4000, 1, 4000, 1, 4000, 1, 4000);
95
96 printf("%" PRId64 "\n", s);
97 return 0;
98}

Generated with cgit - Back to sebastiano.tronto.net