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/18 | |
| parent | 83adb5e4215a25d17cfc11b4dbf10cf20c418c20 (diff) | |
| download | aoc-1f75d7c9ebec207c8193754792076dc66eba9713.tar.gz aoc-1f75d7c9ebec207c8193754792076dc66eba9713.zip | |
Added solutions for 15, 16, 17, 18 and 19
Diffstat (limited to '2023/18')
| -rw-r--r-- | 2023/18/18b.c | 92 |
1 files changed, 92 insertions, 0 deletions
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 | } | ||
