Advent of Code

Diff
Login

Diff

Differences From Artifact [c69db65f02]:

To Artifact [57ed145cda]:


1
2
3
4
5
6
7
8

9
10
11
12
13
14
15
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "aocutils.h"

void aoc202403(char *data, [[maybe_unused]] size_t len) {

    int 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 (;;) {







|
>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <ctype.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];
    char *rest = data;
    char *doleft = data;
    char *dorite = strstr(data + 1, "do()");
    char *dontleft = data;
    char *dontrite = strstr(dontleft + 1, "don't()");
    for (;;) {
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
            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] = (int)strtol(rest, &err, 10);
                if (*err == ',') {
                    if (isdigit((unsigned char)err[1])) {
                        rest = err + 1;
                        term[1] = (int)strtol(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;
                        }
                    }







|



|







25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
            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);
                if (*err == ',') {
                    if (isdigit((unsigned char)err[1])) {
                        rest = err + 1;
                        term[1] = strtol(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;
                        }
                    }
71
72
73
74
75
76
77
78

79
80
81
82
83
84
85
        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;
}

void aoc202402(char *data, [[maybe_unused]] size_t len) {

    int safe = 0, safe2 = 0;
    char *line = strtok(data, "\n");
    while (line) {
        int *arr = NULL;
        int narr = text2array(&arr, line);
        if (safereport(arr, narr)) {
            safe += 1;







|
>







72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
        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;
}

void aoc202402(char *data, size_t len) {
    (void)len; // unused argument
    int safe = 0, safe2 = 0;
    char *line = strtok(data, "\n");
    while (line) {
        int *arr = NULL;
        int narr = text2array(&arr, line);
        if (safereport(arr, narr)) {
            safe += 1;
98
99
100
101
102
103
104
105

106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
    return *(const int *)a - *(const int *)b;
}

#ifdef LISTSIZE
#  error LISTSIZE already defined
#endif
#define LISTSIZE 1200
void aoc202401(char *data, [[maybe_unused]] size_t len) {

    int v1, v2;                                  // values from data
    char *err;
    int list1[LISTSIZE], list2[LISTSIZE];        // the lists
    int n1 = 0, n2 = 0;
    while ((v1 = (int)strtol(data, &err, 10))) { // assume well-formatted data
        data = err;
        v2 = (int)strtoul(data, &err, 10);
        data = err;
        list1[n1++] = v1;                        // add v1 to list1
        list2[n2++] = v2;                        // add v2 to list2
    }
    // redundant check :-)
    if (n1 != n2) printf("Error: list are not the same size\n");

    // sort the lists
    qsort(list1, (size_t)n1, sizeof *list1, delta);
    qsort(list2, (size_t)n2, sizeof *list2, delta);

    // part1
    int sumdeltas = 0;
    for (int k = 0; k < n1; k++) {
        sumdeltas += abs(list1[k] - list2[k]);
    }
    printf("Total distance between lists is {%d}.\n", sumdeltas);

    // part2
    int similarity = 0;
    for (int k = 0; k < n1; k++) {
#if 1 // use the fact lists are sorted: complexity: O(n log n)
        int 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
        int *p = bsearch(list1 + k, list2, (size_t)n2, sizeof *list2, delta);
        if (p) {
            int idxl = (int)(p - list2); // search backwards and forwards in list2
            int idxr = (int)(p - list2); // for the k'th value in list1
            while ((idxl > 0) && (list2[idxl - 1] == *p)) idxl -= 1;
            while ((idxr < n2 - 1) && (list2[idxr + 1] == *p)) idxr += 1;
            int 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
        int count = 0;
        for (int kk = 0; kk < n2; kk++) {
            if (list1[k] == list2[kk]) count++;
        }
        similarity += list1[k] * count;
#endif
    }
    printf("Similarity score between lists is {%d}.\n", similarity);
}
#undef LISTSIZE







|
>
|

|
|
|

|

|
|





|
|


|
|
|

|


|
|

|


|

|
|

|
|





|
|





|


100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
    return *(const int *)a - *(const int *)b;
}

#ifdef LISTSIZE
#  error LISTSIZE already defined
#endif
#define LISTSIZE 1200
void aoc202401(char *data, size_t len) {
    (void)len; // unused argument
    unsigned v[2];                                 // values from data
    char *err;
    unsigned list1[LISTSIZE], list2[LISTSIZE];     // the lists
    size_t n1 = 0, n2 = 0;
    while ((v[0] = strtoul(data, &err, 10))) {     // assume well-formatted data
        data = err;
        v[1] = strtoul(data, &err, 10);
        data = err;
        list1[n1++] = v[0];                        // add v[0] to list1
        list2[n2++] = v[1];                        // add v[1] to list2
    }
    // redundant check :-)
    if (n1 != n2) printf("Error: list are not the same size\n");

    // sort the lists
    qsort(list1, n1, sizeof *list1, delta);
    qsort(list2, n2, sizeof *list2, delta);

    // part1
    unsigned sumdeltas = 0;
    for (size_t k = 0; k < n1; k++) {
        sumdeltas += (list1[k] > list2[k]) ? list1[k] - list2[k] : list2[k] - list1[k];
    }
    printf("Total distance between lists is {%u}.\n", sumdeltas);

    // part2
    unsigned similarity = 0;
    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
            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
            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++) {
            if (list1[k] == list2[kk]) count++;
        }
        similarity += list1[k] * count;
#endif
    }
    printf("Similarity score between lists is {%u}.\n", similarity);
}
#undef LISTSIZE