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
|