diff options
| author | Sebastiano Tronto <sebastiano@tronto.net> | 2023-12-19 15:54:12 +0100 |
|---|---|---|
| committer | Sebastiano Tronto <sebastiano@tronto.net> | 2023-12-19 15:54:12 +0100 |
| commit | 1f75d7c9ebec207c8193754792076dc66eba9713 (patch) | |
| tree | 48556a419f050153513cd5a3b8a4a6e125ba2c45 /2023 | |
| parent | 83adb5e4215a25d17cfc11b4dbf10cf20c418c20 (diff) | |
| download | aoc-1f75d7c9ebec207c8193754792076dc66eba9713.tar.gz aoc-1f75d7c9ebec207c8193754792076dc66eba9713.zip | |
Added solutions for 15, 16, 17, 18 and 19
Diffstat (limited to '2023')
| -rw-r--r-- | 2023/15/15a.c | 21 | ||||
| -rw-r--r-- | 2023/15/15b.c | 48 | ||||
| -rw-r--r-- | 2023/16/16a.c | 37 | ||||
| -rw-r--r-- | 2023/16/16b.c | 51 | ||||
| -rw-r--r-- | 2023/17/17a.c | 73 | ||||
| -rw-r--r-- | 2023/17/17b.c | 74 | ||||
| -rw-r--r-- | 2023/18/18b.c | 92 | ||||
| -rw-r--r-- | 2023/19/19a.c | 87 | ||||
| -rw-r--r-- | 2023/19/19b.c | 98 |
9 files changed, 581 insertions, 0 deletions
diff --git a/2023/15/15a.c b/2023/15/15a.c new file mode 100644 index 0000000..16a8fec --- /dev/null +++ b/2023/15/15a.c | |||
| @@ -0,0 +1,21 @@ | |||
| 1 | #include <stdio.h> | ||
| 2 | |||
| 3 | #define N 100000 | ||
| 4 | |||
| 5 | char *b, line[N]; | ||
| 6 | int c, s; | ||
| 7 | |||
| 8 | int main() { | ||
| 9 | fgets(line, N, stdin); | ||
| 10 | |||
| 11 | for (b = line, c = 0, s = 0; *b; b++) { | ||
| 12 | if (*b == ',' || *b == '\n') { | ||
| 13 | s += c; | ||
| 14 | c = 0; | ||
| 15 | } else | ||
| 16 | c = (c + (int)*b) * 17 % 256; | ||
| 17 | } | ||
| 18 | |||
| 19 | printf("%d\n", s); | ||
| 20 | return 0; | ||
| 21 | } | ||
diff --git a/2023/15/15b.c b/2023/15/15b.c new file mode 100644 index 0000000..15b97f9 --- /dev/null +++ b/2023/15/15b.c | |||
| @@ -0,0 +1,48 @@ | |||
| 1 | #include <inttypes.h> | ||
| 2 | #include <stdio.h> | ||
| 3 | |||
| 4 | #define N 100000 | ||
| 5 | |||
| 6 | char *b, line[N]; | ||
| 7 | int64_t c, l, s, n[256], box[256][N]; | ||
| 8 | |||
| 9 | int main() { | ||
| 10 | fgets(line, N, stdin); | ||
| 11 | |||
| 12 | for (b = line, c = 0; *b != '\n'; b++) { | ||
| 13 | switch (*b) { | ||
| 14 | case ',': | ||
| 15 | c = 0; | ||
| 16 | l = 0; | ||
| 17 | break; | ||
| 18 | case '=': | ||
| 19 | int64_t i; | ||
| 20 | for (i = 0; i < n[c]; i++) | ||
| 21 | if (box[c][i] / 10 == l) | ||
| 22 | break; | ||
| 23 | if (i == n[c]) n[c]++; | ||
| 24 | box[c][i] = l * 10 + (int)(*(++b)-'0'); | ||
| 25 | break; | ||
| 26 | case '-': | ||
| 27 | for (int64_t i = 0; i < n[c]; i++) { | ||
| 28 | if (box[c][i] / 10 == l) { | ||
| 29 | for (int j = i+1; j < n[c]; j++) | ||
| 30 | box[c][j-1] = box[c][j]; | ||
| 31 | n[c]--; | ||
| 32 | } | ||
| 33 | } | ||
| 34 | break; | ||
| 35 | default: | ||
| 36 | c = (c + (int)*b) * 17 % 256; | ||
| 37 | l = l*256 + (int)*b; | ||
| 38 | break; | ||
| 39 | } | ||
| 40 | } | ||
| 41 | |||
| 42 | for (int64_t i = 0; i < 256; i++) | ||
| 43 | for (int64_t j = 0; j < n[i]; j++) | ||
| 44 | s += (i+1) * (j+1) * (box[i][j]%10); | ||
| 45 | |||
| 46 | printf("%" PRId64 "\n", s); | ||
| 47 | return 0; | ||
| 48 | } | ||
diff --git a/2023/16/16a.c b/2023/16/16a.c new file mode 100644 index 0000000..0f95553 --- /dev/null +++ b/2023/16/16a.c | |||
| @@ -0,0 +1,37 @@ | |||
| 1 | #include <stdbool.h> | ||
| 2 | #include <stdio.h> | ||
| 3 | #include <stdlib.h> | ||
| 4 | #include <string.h> | ||
| 5 | |||
| 6 | #define M 200 | ||
| 7 | |||
| 8 | char map[M][M]; | ||
| 9 | int s, n, nb, b[M][2], entered[M][M]; | ||
| 10 | |||
| 11 | #define E 1 | ||
| 12 | #define N 2 | ||
| 13 | #define W 4 | ||
| 14 | #define S 8 | ||
| 15 | int turn[9][255] = { | ||
| 16 | [E] = { ['.'] = E, ['-'] = E, ['/'] = N, ['\\'] = S, ['|'] = N|S }, | ||
| 17 | [N] = { ['.'] = N, ['-'] = E|W, ['/'] = E, ['\\'] = W, ['|'] = N }, | ||
| 18 | [W] = { ['.'] = W, ['-'] = W, ['/'] = S, ['\\'] = N, ['|'] = N|S }, | ||
| 19 | [S] = { ['.'] = S, ['-'] = E|W, ['/'] = W, ['\\'] = E, ['|'] = S }, | ||
| 20 | }; | ||
| 21 | int go[9][2] = { [E] = {0, 1}, [N] = {-1, 0}, [W] = {0, -1}, [S] = {1, 0} }; | ||
| 22 | |||
| 23 | void walk(int i, int j, int d) { | ||
| 24 | if (i < 0 || j < 0 || i >= n || j >= n || (entered[i][j] & d)) return; | ||
| 25 | if (!entered[i][j]) s++; | ||
| 26 | entered[i][j] |= d; | ||
| 27 | for (int k = 1; k <= 8; k <<= 1) | ||
| 28 | if (k & turn[d][map[i][j]]) | ||
| 29 | walk(i+go[k][0], j+go[k][1], k); | ||
| 30 | } | ||
| 31 | |||
| 32 | int main() { | ||
| 33 | for (n = 0; fgets(map[n], M, stdin) != NULL; n++) ; | ||
| 34 | walk(0, 0, E); | ||
| 35 | printf("%d\n", s); | ||
| 36 | return 0; | ||
| 37 | } | ||
diff --git a/2023/16/16b.c b/2023/16/16b.c new file mode 100644 index 0000000..ce42c31 --- /dev/null +++ b/2023/16/16b.c | |||
| @@ -0,0 +1,51 @@ | |||
| 1 | #include <stdbool.h> | ||
| 2 | #include <stdio.h> | ||
| 3 | #include <stdlib.h> | ||
| 4 | #include <string.h> | ||
| 5 | |||
| 6 | #define M 200 | ||
| 7 | #define MAX(x,y) ((x)>(y)?(x):(y)) | ||
| 8 | |||
| 9 | char map[M][M]; | ||
| 10 | int s, t, n, nb, b[M][2], entered[M][M]; | ||
| 11 | |||
| 12 | #define E 1 | ||
| 13 | #define N 2 | ||
| 14 | #define W 4 | ||
| 15 | #define S 8 | ||
| 16 | int turn[9][255] = { | ||
| 17 | [E] = { ['.'] = E, ['-'] = E, ['/'] = N, ['\\'] = S, ['|'] = N|S }, | ||
| 18 | [N] = { ['.'] = N, ['-'] = E|W, ['/'] = E, ['\\'] = W, ['|'] = N }, | ||
| 19 | [W] = { ['.'] = W, ['-'] = W, ['/'] = S, ['\\'] = N, ['|'] = N|S }, | ||
| 20 | [S] = { ['.'] = S, ['-'] = E|W, ['/'] = W, ['\\'] = E, ['|'] = S }, | ||
| 21 | }; | ||
| 22 | int go[9][2] = { [E] = {0, 1}, [N] = {-1, 0}, [W] = {0, -1}, [S] = {1, 0} }; | ||
| 23 | |||
| 24 | void walk(int i, int j, int d) { | ||
| 25 | if (i < 0 || j < 0 || i >= n || j >= n || (entered[i][j] & d)) return; | ||
| 26 | if (!entered[i][j]) s++; | ||
| 27 | entered[i][j] |= d; | ||
| 28 | for (int k = 1; k <= 8; k <<= 1) | ||
| 29 | if (k & turn[d][map[i][j]]) | ||
| 30 | walk(i+go[k][0], j+go[k][1], k); | ||
| 31 | } | ||
| 32 | |||
| 33 | void clear(void) { | ||
| 34 | s = 0; | ||
| 35 | for (int i = 0; i < n; i++) | ||
| 36 | memset(entered[i], 0, n * sizeof(int)); | ||
| 37 | } | ||
| 38 | |||
| 39 | int main() { | ||
| 40 | for (n = 0; fgets(map[n], M, stdin) != NULL; n++) ; | ||
| 41 | |||
| 42 | for (int i = 0; i < n; i++) { | ||
| 43 | clear(); walk(i, 0, E); t = MAX(s, t); | ||
| 44 | clear(); walk(i, n-1, W); t = MAX(s, t); | ||
| 45 | clear(); walk(0, i, S); t = MAX(s, t); | ||
| 46 | clear(); walk(n-1, i, N); t = MAX(s, t); | ||
| 47 | } | ||
| 48 | |||
| 49 | printf("%d\n", t); | ||
| 50 | return 0; | ||
| 51 | } | ||
diff --git a/2023/17/17a.c b/2023/17/17a.c new file mode 100644 index 0000000..0b02f45 --- /dev/null +++ b/2023/17/17a.c | |||
| @@ -0,0 +1,73 @@ | |||
| 1 | #include <stdbool.h> | ||
| 2 | #include <stdio.h> | ||
| 3 | #include <stdlib.h> | ||
| 4 | #include <string.h> | ||
| 5 | |||
| 6 | #define M 150 | ||
| 7 | #define MAXE 1000000 | ||
| 8 | #define INF 999999999 | ||
| 9 | |||
| 10 | #define E 0 | ||
| 11 | #define N 1 | ||
| 12 | #define W 2 | ||
| 13 | #define S 3 | ||
| 14 | |||
| 15 | int go[4][2] = { [E] = {0, 1}, [N] = {-1, 0}, [W] = {0, -1}, [S] = {1, 0} }; | ||
| 16 | |||
| 17 | typedef struct { int i, j, k, s, d; } node_t; | ||
| 18 | |||
| 19 | char map[M][M]; | ||
| 20 | int n, nq, d[M][M][4][4]; | ||
| 21 | node_t heap[MAXE]; | ||
| 22 | |||
| 23 | void swap(int i, int j) { | ||
| 24 | node_t aux = heap[i]; | ||
| 25 | heap[i] = heap[j]; | ||
| 26 | heap[j] = aux; | ||
| 27 | } | ||
| 28 | |||
| 29 | void push(node_t node) { | ||
| 30 | heap[nq] = node; | ||
| 31 | for (int k = nq++; k > 0 && heap[k].d < heap[(k-1)/2].d; k = (k-1)/2) | ||
| 32 | swap(k, (k-1)/2); | ||
| 33 | } | ||
| 34 | |||
| 35 | node_t pop(void) { | ||
| 36 | node_t ret = heap[0]; | ||
| 37 | heap[0] = heap[--nq]; | ||
| 38 | for (int k = 0, j = 0; 2*k+1 < nq; k = j) { | ||
| 39 | j = 2*k+1; | ||
| 40 | if (j+1 < nq && heap[j].d > heap[j+1].d) j++; | ||
| 41 | if (heap[k].d > heap[j].d) swap(k, j); | ||
| 42 | } | ||
| 43 | return ret; | ||
| 44 | } | ||
| 45 | |||
| 46 | int main() { | ||
| 47 | for (n = 0; fgets(map[n], M, stdin) != NULL; n++) ; | ||
| 48 | |||
| 49 | for (int i = 0; i < n; i++) | ||
| 50 | for (int j = 0; j < n; j++) | ||
| 51 | for (int k = 0; k < 4; k++) | ||
| 52 | for (int s = 0; s < 4; s++) | ||
| 53 | d[i][j][k][s] = INF; | ||
| 54 | |||
| 55 | push((node_t){.i = 0, .j = 0, .k = -1, .s = 0}); | ||
| 56 | node_t v; | ||
| 57 | for (v = pop(); v.i != n-1 || v.j != n-1; v = pop()) { | ||
| 58 | for (int k = 0; k < 4; k++) { | ||
| 59 | if (k == v.k + 2 || k == v.k - 2) continue; | ||
| 60 | int ii = v.i+go[k][0]; | ||
| 61 | int jj = v.j+go[k][1]; | ||
| 62 | if (ii < 0 || jj < 0 || ii >= n || jj >= n) continue; | ||
| 63 | int ss = k == v.k ? v.s + 1 : 1; | ||
| 64 | int dd = v.d + map[ii][jj] - '0'; | ||
| 65 | if (d[ii][jj][k][ss] <= dd || ss > 3) continue; | ||
| 66 | d[ii][jj][k][ss] = dd; | ||
| 67 | push((node_t){.i=ii, .j=jj, .k=k, .s=ss, .d=dd}); | ||
| 68 | } | ||
| 69 | } | ||
| 70 | |||
| 71 | printf("%d\n", v.d); | ||
| 72 | return 0; | ||
| 73 | } | ||
diff --git a/2023/17/17b.c b/2023/17/17b.c new file mode 100644 index 0000000..10fad81 --- /dev/null +++ b/2023/17/17b.c | |||
| @@ -0,0 +1,74 @@ | |||
| 1 | #include <stdbool.h> | ||
| 2 | #include <stdio.h> | ||
| 3 | #include <stdlib.h> | ||
| 4 | #include <string.h> | ||
| 5 | |||
| 6 | #define M 150 | ||
| 7 | #define MAXE 1000000 | ||
| 8 | #define INF 999999999 | ||
| 9 | |||
| 10 | #define E 0 | ||
| 11 | #define N 1 | ||
| 12 | #define W 2 | ||
| 13 | #define S 3 | ||
| 14 | |||
| 15 | int go[4][2] = { [E] = {0, 1}, [N] = {-1, 0}, [W] = {0, -1}, [S] = {1, 0} }; | ||
| 16 | |||
| 17 | typedef struct { int i, j, k, s, d; } node_t; | ||
| 18 | |||
| 19 | char map[M][M]; | ||
| 20 | int n, nq, d[M][M][4][11]; | ||
| 21 | node_t heap[MAXE]; | ||
| 22 | |||
| 23 | void swap(int i, int j) { | ||
| 24 | node_t aux = heap[i]; | ||
| 25 | heap[i] = heap[j]; | ||
| 26 | heap[j] = aux; | ||
| 27 | } | ||
| 28 | |||
| 29 | void push(node_t node) { | ||
| 30 | heap[nq] = node; | ||
| 31 | for (int k = nq++; k > 0 && heap[k].d < heap[(k-1)/2].d; k = (k-1)/2) | ||
| 32 | swap(k, (k-1)/2); | ||
| 33 | } | ||
| 34 | |||
| 35 | node_t pop(void) { | ||
| 36 | node_t ret = heap[0]; | ||
| 37 | heap[0] = heap[--nq]; | ||
| 38 | for (int k = 0, j = 0; 2*k+1 < nq; k = j) { | ||
| 39 | j = 2*k+1; | ||
| 40 | if (j+1 < nq && heap[j].d > heap[j+1].d) j++; | ||
| 41 | if (heap[k].d > heap[j].d) swap(k, j); | ||
| 42 | } | ||
| 43 | return ret; | ||
| 44 | } | ||
| 45 | |||
| 46 | int main() { | ||
| 47 | for (n = 0; fgets(map[n], M, stdin) != NULL; n++) ; | ||
| 48 | |||
| 49 | for (int i = 0; i < n; i++) | ||
| 50 | for (int j = 0; j < n; j++) | ||
| 51 | for (int k = 0; k < 4; k++) | ||
| 52 | for (int s = 0; s < 11; s++) | ||
| 53 | d[i][j][k][s] = INF; | ||
| 54 | |||
| 55 | push((node_t){.i = 0, .j = 0, .k = -1, .s = 0}); | ||
| 56 | node_t v; | ||
| 57 | for (v = pop(); v.i != n-1 || v.j != n-1; v = pop()) { | ||
| 58 | for (int k = 0; k < 4; k++) { | ||
| 59 | if (k == v.k + 2 || k == v.k - 2) continue; | ||
| 60 | if (v.s < 4 && v.k != -1 && v.k != k) continue; | ||
| 61 | int ii = v.i+go[k][0]; | ||
| 62 | int jj = v.j+go[k][1]; | ||
| 63 | if (ii < 0 || jj < 0 || ii >= n || jj >= n) continue; | ||
| 64 | int ss = k == v.k ? v.s + 1 : 1; | ||
| 65 | int dd = v.d + map[ii][jj] - '0'; | ||
| 66 | if (d[ii][jj][k][ss] <= dd || ss > 10) continue; | ||
| 67 | d[ii][jj][k][ss] = dd; | ||
| 68 | push((node_t){.i=ii, .j=jj, .k=k, .s=ss, .d=dd}); | ||
| 69 | } | ||
| 70 | } | ||
| 71 | |||
| 72 | printf("%d\n", v.d); | ||
| 73 | return 0; | ||
| 74 | } | ||
diff --git a/2023/18/18b.c b/2023/18/18b.c new file mode 100644 index 0000000..d79d4cb --- /dev/null +++ b/2023/18/18b.c | |||
| @@ -0,0 +1,92 @@ | |||
| 1 | /* | ||
| 2 | I have lost my code for part one. It reused some stuff from day 10. | ||
| 3 | This code can be adjusted to work for part one, just change the input reading. | ||
| 4 | */ | ||
| 5 | |||
| 6 | #include <inttypes.h> | ||
| 7 | #include <stdio.h> | ||
| 8 | #include <stdlib.h> | ||
| 9 | #include <string.h> | ||
| 10 | |||
| 11 | #define N 1000 | ||
| 12 | #define MAX(x,y) ((x)>(y)?(x):(y)) | ||
| 13 | #define MIN(x,y) ((x)<(y)?(x):(y)) | ||
| 14 | |||
| 15 | typedef struct { int64_t i, j; } point_t; | ||
| 16 | |||
| 17 | char *buf, in[50]; | ||
| 18 | int64_t k, l, oldl, n, r, t, nolda, nb, a[N], olda[N], b[N]; | ||
| 19 | point_t p[N]; | ||
| 20 | point_t go[] = {{.i=0, .j=1}, {.i=1, .j=0}, {.i=0, .j=-1}, {.i=-1, .j=0}}; | ||
| 21 | |||
| 22 | int cmp_int64(const void *x, const void *y) { | ||
| 23 | const int64_t *a = x, *b = y; | ||
| 24 | return *a > *b ? 1 : (*a < *b) ? -1 : 0; | ||
| 25 | } | ||
| 26 | |||
| 27 | int cmp_point(const void *x, const void *y) { | ||
| 28 | const point_t *p = x, *q = y; | ||
| 29 | int a = cmp_int64(&p->i, &q->i); | ||
| 30 | int b = cmp_int64(&p->j, &q->j); | ||
| 31 | return a ? a : b; | ||
| 32 | } | ||
| 33 | |||
| 34 | int64_t val(char c) { | ||
| 35 | if (c >= '0' && c <= '9') return c - '0'; | ||
| 36 | return c - 'a' + 10; | ||
| 37 | } | ||
| 38 | |||
| 39 | int64_t removedoubles(int64_t a[], int64_t n) { | ||
| 40 | int64_t i, j = 0; | ||
| 41 | for (i = 0; i < n; i++) { | ||
| 42 | a[j] = a[i]; | ||
| 43 | if (i+1 < n && a[j] == a[i+1]) | ||
| 44 | i++; | ||
| 45 | else | ||
| 46 | j++; | ||
| 47 | } | ||
| 48 | return j; | ||
| 49 | } | ||
| 50 | |||
| 51 | int64_t overlaplen(int64_t a[], int64_t na, int64_t b[], int64_t nb) { | ||
| 52 | int64_t ret = 0; | ||
| 53 | for (int64_t i = 0; 2*i+1 < na; i++) | ||
| 54 | for (int64_t j = 0; 2*j+1 < nb; j++) | ||
| 55 | ret += MAX(0, | ||
| 56 | MIN(a[2*i+1], b[2*j+1]) - MAX(a[2*i], b[2*j]) + 1); | ||
| 57 | return ret; | ||
| 58 | } | ||
| 59 | |||
| 60 | int64_t linelen(int64_t a[], int64_t n) { | ||
| 61 | return overlaplen(a, n, a, n); | ||
| 62 | } | ||
| 63 | |||
| 64 | int main() { | ||
| 65 | p[n++] = (point_t) {0}; | ||
| 66 | while ((buf = fgets(in, 50, stdin)) != NULL) { | ||
| 67 | while (*buf != '#') buf++; | ||
| 68 | k = 0; | ||
| 69 | for (int i = 1; i < 6; i++) | ||
| 70 | k = 16*k + val(*(buf+i)); | ||
| 71 | point_t d = go[*(buf+6) - '0']; | ||
| 72 | p[n] = (point_t){.i = p[n-1].i+d.i*k, .j = p[n-1].j+d.j*k}; | ||
| 73 | n++; | ||
| 74 | } | ||
| 75 | |||
| 76 | qsort(p, --n, sizeof(point_t), &cmp_point); | ||
| 77 | |||
| 78 | for (int64_t i = 0, ia = 0; i < n-1; i++) { | ||
| 79 | a[ia++] = p[i].j; | ||
| 80 | if (p[i].i != p[i+1].i) { | ||
| 81 | qsort(a, ia, sizeof(int64_t), &cmp_int64); | ||
| 82 | ia = removedoubles(a, ia); | ||
| 83 | t += linelen(a, ia) * (p[i+1].i - p[i].i + 1) - | ||
| 84 | overlaplen(a, ia, olda, nolda); | ||
| 85 | nolda = ia; | ||
| 86 | memcpy(olda, a, nolda * sizeof(int64_t)); | ||
| 87 | } | ||
| 88 | } | ||
| 89 | |||
| 90 | printf("%" PRId64 "\n", t); | ||
| 91 | return 0; | ||
| 92 | } | ||
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 | |||
| 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 | } | ||
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 | |||
| 10 | typedef struct { int64_t val[26]; } part_t; | ||
| 11 | typedef struct { char v, comp, wnext[10]; int64_t b; } rule_t; | ||
| 12 | typedef struct { char name[50]; int64_t n; rule_t r[100]; } workflow_t; | ||
| 13 | |||
| 14 | int64_t nw, A; | ||
| 15 | workflow_t w[N]; | ||
| 16 | part_t p[N]; | ||
| 17 | |||
| 18 | workflow_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 | |||
| 38 | workflow_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 | |||
| 46 | int64_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 | |||
| 88 | int 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 | } | ||
