aboutsummaryrefslogtreecommitdiff
path: root/2023
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
parent83adb5e4215a25d17cfc11b4dbf10cf20c418c20 (diff)
downloadaoc-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.c21
-rw-r--r--2023/15/15b.c48
-rw-r--r--2023/16/16a.c37
-rw-r--r--2023/16/16b.c51
-rw-r--r--2023/17/17a.c73
-rw-r--r--2023/17/17b.c74
-rw-r--r--2023/18/18b.c92
-rw-r--r--2023/19/19a.c87
-rw-r--r--2023/19/19b.c98
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
5char *b, line[N];
6int c, s;
7
8int 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
6char *b, line[N];
7int64_t c, l, s, n[256], box[256][N];
8
9int 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
8char map[M][M];
9int 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
15int 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};
21int go[9][2] = { [E] = {0, 1}, [N] = {-1, 0}, [W] = {0, -1}, [S] = {1, 0} };
22
23void 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
32int 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
9char map[M][M];
10int 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
16int 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};
22int go[9][2] = { [E] = {0, 1}, [N] = {-1, 0}, [W] = {0, -1}, [S] = {1, 0} };
23
24void 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
33void clear(void) {
34 s = 0;
35 for (int i = 0; i < n; i++)
36 memset(entered[i], 0, n * sizeof(int));
37}
38
39int 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
15int go[4][2] = { [E] = {0, 1}, [N] = {-1, 0}, [W] = {0, -1}, [S] = {1, 0} };
16
17typedef struct { int i, j, k, s, d; } node_t;
18
19char map[M][M];
20int n, nq, d[M][M][4][4];
21node_t heap[MAXE];
22
23void swap(int i, int j) {
24 node_t aux = heap[i];
25 heap[i] = heap[j];
26 heap[j] = aux;
27}
28
29void 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
35node_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
46int 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
15int go[4][2] = { [E] = {0, 1}, [N] = {-1, 0}, [W] = {0, -1}, [S] = {1, 0} };
16
17typedef struct { int i, j, k, s, d; } node_t;
18
19char map[M][M];
20int n, nq, d[M][M][4][11];
21node_t heap[MAXE];
22
23void swap(int i, int j) {
24 node_t aux = heap[i];
25 heap[i] = heap[j];
26 heap[j] = aux;
27}
28
29void 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
35node_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
46int 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/*
2I have lost my code for part one. It reused some stuff from day 10.
3This 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
15typedef struct { int64_t i, j; } point_t;
16
17char *buf, in[50];
18int64_t k, l, oldl, n, r, t, nolda, nb, a[N], olda[N], b[N];
19point_t p[N];
20point_t go[] = {{.i=0, .j=1}, {.i=1, .j=0}, {.i=0, .j=-1}, {.i=-1, .j=0}};
21
22int 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
27int 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
34int64_t val(char c) {
35 if (c >= '0' && c <= '9') return c - '0';
36 return c - 'a' + 10;
37}
38
39int64_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
51int64_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
60int64_t linelen(int64_t a[], int64_t n) {
61 return overlaplen(a, n, a, n);
62}
63
64int 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
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