Advent of Code

Diff
Login

Diff

Differences From Artifact [57ed145cda]:

To Artifact [f495d3d009]:


1


2
3
4
5
6
7
8
9
10

11
12
13
14
15
16
17
1
2
3
4
5
6
7
8
9
10
11

12
13
14
15
16
17
18
19

+
+








-
+







#include <ctype.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "aocutils.h"

void aoc202403(char *data, size_t len) {
    (void)len; // unused argument
    int sumproducts = 0, sumproducts2 = 0, term[2];
    unsigned sumproducts = 0, sumproducts2 = 0, term[2];
    char *rest = data;
    char *doleft = data;
    char *dorite = strstr(data + 1, "do()");
    char *dontleft = data;
    char *dontrite = strstr(dontleft + 1, "don't()");
    for (;;) {
        char *mul = strstr(rest, "mul(");
25
26
27
28
29
30
31
32

33
34
35
36

37
38
39
40
41
42
43
44
45
46
47
48
49
50
51


52
53
54

55
56
57
58
59



60
61

62
63

64
65
66

67
68
69
70
71
72
73
74
75
76








77
78
79
80
81

82
83
84
85


86
87
88
89
90

91
92
93
94
95
96


97
98
99




100

101
102
103
104
105
106
107
27
28
29
30
31
32
33

34
35
36
37

38
39
40
41
42
43
44
45
46
47
48
49
50
51


52
53
54
55

56
57
58



59
60
61
62

63
64

65
66
67

68
69
70








71
72
73
74
75
76
77
78
79
80
81
82

83
84
85


86
87
88
89
90
91

92
93
94
95
96


97
98
99
100
101
102
103
104
105

106
107
108
109
110
111
112
113







-
+



-
+













-
-
+
+


-
+


-
-
-
+
+
+

-
+

-
+


-
+


-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+




-
+


-
-
+
+




-
+




-
-
+
+



+
+
+
+
-
+







            while (dontrite && (mul > dontrite)) {
                dontleft = dontrite;
                dontrite = strstr(dontrite + 1, "don't()");
            }
            rest = mul + 4;
            if (isdigit((unsigned char)rest[0])) {
                char *err;
                term[0] = strtol(rest, &err, 10);
                term[0] = strtoul(rest, &err, 10);
                if (*err == ',') {
                    if (isdigit((unsigned char)err[1])) {
                        rest = err + 1;
                        term[1] = strtol(rest, &err, 10);
                        term[1] = strtoul(rest, &err, 10);
                        if (*err == ')') {
                            sumproducts += term[0] * term[1];
                            // multiply by 0 if closest conditional to the left is "don't()"
                            sumproducts2 += (doleft >= dontleft) * (term[0] * term[1]);
                            rest = err + 1;
                        }
                    }
                }
            }
        } else {
            break;
        }
    }
    printf("The sum of the products is {%d}.\n", sumproducts);
    printf("The sum of the products with conditionals is {%d}.\n", sumproducts2);
    printf("The sum of the products is {%u}.\n", sumproducts);
    printf("The sum of the products with conditionals is {%u}.\n", sumproducts2);
}

static int safereport(int *v, int nv) {
static bool safereport(unsigned *v, size_t nv) {
    int dir = 1;               // ascending
    if (v[0] > v[1]) dir = -1; // descending
    for (int k = 1; k < nv; k++) {
        if (v[k-1] == v[k]) return 0;
        if (abs(v[k-1] - v[k]) > 3) return 0;
    for (size_t k = 1; k < nv; k++) {
        if (v[k-1] == v[k]) return false;
        if (distance(v[k-1], v[k]) > 3) return false;
        if (dir == -1) {
            if (v[k-1] < v[k]) return 0;
            if (v[k-1] < v[k]) return false;
        } else {
            if (v[k-1] > v[k]) return 0;
            if (v[k-1] > v[k]) return false;
        }
    }
    return 1;
    return true;
}

static int safereportdamp(int *v, int nv) {
    for (int swap = 0; swap < nv; swap++) {           //              abcde
        int tmp = v[swap];                            // swap(0, 0): a-bcde
        v[swap] = v[0];                               // swap(1, 0): b-acde
        v[0] = tmp;                                   // swap(2, 0): c-abde
        if (safereport(v + 1, nv - 1)) return 1;      // swap(3, 0): d-abce
    }                                                 // ... and so on
    return 0;
static bool safereportdamp(unsigned *v, size_t nv) {
    for (size_t swap = 0; swap < nv; swap++) {       //               abcd...wx
        unsigned tmp = v[swap];                      // swap(0,   0): abcd...wx
        v[swap] = v[0];                              // swap(1,   0): bacd...wx
        v[0] = tmp;                                  // swap(2,   0): cabd...wx
        if (safereport(v + 1, nv - 1)) return true;  // ... and so on ...
    }                                                // swap(n-1, 0): xabc...vw
    return false;
}

void aoc202402(char *data, size_t len) {
    (void)len; // unused argument
    int safe = 0, safe2 = 0;
    unsigned safe = 0, safe2 = 0;
    char *line = strtok(data, "\n");
    while (line) {
        int *arr = NULL;
        int narr = text2array(&arr, line);
        unsigned *arr = NULL;
        size_t narr = text2array(&arr, line);
        if (safereport(arr, narr)) {
            safe += 1;
            safe2 += 1;
        } else {
            safe2 += safereportdamp(arr, narr);
            safe2 += safereportdamp(arr, narr) ? 1 : 0;
        }
        free(arr);
        line = strtok(NULL, "\n");
    }
    printf("There are %d safe reports.\n", safe);
    printf("There are %d safe reports with the Problem Dampener.\n", safe2);
    printf("There are %u safe reports.\n", safe);
    printf("There are %u safe reports with the Problem Dampener.\n", safe2);
}

static int delta(const void *a, const void *b) {
    const unsigned *aa = a;
    const unsigned *bb = b;
    if (*aa > *bb) return 1;
    if (*aa < *bb) return -1;
    return *(const int *)a - *(const int *)b;
    return 0;
}

#ifdef LISTSIZE
#  error LISTSIZE already defined
#endif
#define LISTSIZE 1200
void aoc202401(char *data, size_t len) {
136
137
138
139
140
141
142
143
144


145
146
147

148
149
150
151
152
153
154
142
143
144
145
146
147
148


149
150
151
152

153
154
155
156
157
158
159
160







-
-
+
+


-
+







    for (size_t k = 0; k < n1; k++) {
#if 1 // use the fact lists are sorted: complexity: O(n log n)
        unsigned leftcount = 1; // number of equal values in list1
        while ((k + leftcount < n1) && (list1[k] == list1[k + leftcount])) leftcount++;
        // find list1 k'ths value in list2
        unsigned *p = bsearch(list1 + k, list2, n2, sizeof *list2, delta);
        if (p) {
            int idxl = p - list2; // search backwards and forwards in list2
            int idxr = p - list2; // for the k'th value in list1
            ptrdiff_t idxl = p - list2; // search backwards and forwards in list2
            ptrdiff_t idxr = p - list2; // for the k'th value in list1
            while ((idxl > 0) && (list2[idxl - 1] == *p)) idxl -= 1;
            while ((idxr < (int)n2 - 1) && (list2[idxr + 1] == *p)) idxr += 1;
            unsigned rightcount = (unsigned)(idxr - idxl + 1); // number of repeats in list2
            unsigned rightcount = idxr - idxl + 1; // number of repeats in list2
            similarity += *p * rightcount * leftcount;
        }
        k += leftcount - 1; // adjust loop control variable
#else
        // loop inside loop: complexity O(n^2); don't care lists are sorted
        unsigned count = 0;
        for (size_t kk = 0; kk < n2; kk++) {