Advent of Code

Check-in [7965556304]
Login

Check-in [7965556304]

Overview
Comment:reworked warning options and C standard
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 7965556304e85db4f89fc0fc3715013943b50f941f07f2689a68b61437f6e311
User & Date: nnz on 2024-12-04 08:56:59
Other Links: manifest | tags
Context
2024-12-04
09:27
use unsigned check-in: fe9956e07d user: nnz tags: trunk
08:56
reworked warning options and C standard check-in: 7965556304 user: nnz tags: trunk
2024-12-03
21:04
comment on conditional check-in: 9c47eb77fc user: nnz tags: trunk
Changes

Modified Makefile from [b36c017e36] to [c839dd71d7].

1
2
3
4
5
6
7
8
9
10
11
12


13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

28
29
30
31
32
33
34
35

36
37
38
39








aoc: *.c *.h
	gcc -std=c2x -pedantic \
	-D_XOPEN_SOURCE=800 \
	-flto \
	-O3 -DNDEBUG \
	*.c \
	-o aoc

aocdbg: *.c *.h
	gcc -std=c2x -pedantic \
	-D_XOPEN_SOURCE=800 \
	-Werror -Wall -Wextra \


	-Wbad-function-cast \
	-Wcast-align \
	-Wcast-qual \
	-Wconversion $(: pesky little option; makes my code abuse casts ) \
	-Wfloat-equal \
	-Wformat=2 \
	-Wformat-signedness \
	-Winline \
	-Wlogical-op \
	-Wnested-externs \
	-Wno-missing-braces \
	-Wno-missing-field-initializers \
	-Wold-style-definition \
	-Wpointer-arith \
	-Wredundant-decls \

	-Wshadow \
	-Wstrict-aliasing=2 \
	-Wstrict-overflow=5 \
	-Wstrict-prototypes \
	-Wswitch-default \
	-Wswitch-enum \
	-Wundef \
	-Wunreachable-code \

	-fno-omit-frame-pointer -ffloat-store -fno-common -fstrict-aliasing \
	-Og -ggdb3 \
	*.c \
	-o aocdbg








|
|
<
<
<
|
|


|


>
>



<











>








>




>
>
>
>
>
>
>
>
1
2



3
4
5
6
7
8
9
10
11
12
13
14

15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
all: aocdbg aoc




clean:
	rm aocdbg aoc

aocdbg: *.c *.h
	gcc -std=c99 -pedantic -pedantic-errors \
	-D_XOPEN_SOURCE=800 \
	-Werror -Wall -Wextra \
	-Wc99-c11-compat \
	-Wc11-c2x-compat \
	-Wbad-function-cast \
	-Wcast-align \
	-Wcast-qual \

	-Wfloat-equal \
	-Wformat=2 \
	-Wformat-signedness \
	-Winline \
	-Wlogical-op \
	-Wnested-externs \
	-Wno-missing-braces \
	-Wno-missing-field-initializers \
	-Wold-style-definition \
	-Wpointer-arith \
	-Wredundant-decls \
	-Wsign-conversion \
	-Wshadow \
	-Wstrict-aliasing=2 \
	-Wstrict-overflow=5 \
	-Wstrict-prototypes \
	-Wswitch-default \
	-Wswitch-enum \
	-Wundef \
	-Wunreachable-code \
	-Wvla \
	-fno-omit-frame-pointer -ffloat-store -fno-common -fstrict-aliasing \
	-Og -ggdb3 \
	*.c \
	-o aocdbg

aoc: *.c *.h
	gcc -std=c99 -pedantic -pedantic-errors \
	-D_XOPEN_SOURCE=800 \
	-flto -fno-omit-frame-pointer -ffloat-store -fno-common -fstrict-aliasing \
	-O3 -DNDEBUG \
	*.c \
	-o aoc

Modified aoc.c from [d7e84791d2] to [c6fa85498d].

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#define MAX_YEAR 2024

int main(int argc, char **argv) {
    int y = 0, d = 0;
    char dataname[99];
    if (argc >= 3) {
        char *err;
        y = (int)strtol(argv[1], &err, 10);
        if (err && *err) y = 0;
        if (y < 2015) y = 0;
        if (y > MAX_YEAR) y = 0;
        d = (int)strtol(argv[2], &err, 10);
        if (err && *err) d = 0;
        if (d < 1) d = 0;
        if (d > 25) d = 0;
        if (argc >= 4) {
            sprintf(dataname, "%.98s", argv[3]);
        } else {
            sprintf(dataname, ".%04d%02d.txt", y, d);







|



|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#define MAX_YEAR 2024

int main(int argc, char **argv) {
    int y = 0, d = 0;
    char dataname[99];
    if (argc >= 3) {
        char *err;
        y = strtol(argv[1], &err, 10);
        if (err && *err) y = 0;
        if (y < 2015) y = 0;
        if (y > MAX_YEAR) y = 0;
        d = strtol(argv[2], &err, 10);
        if (err && *err) d = 0;
        if (d < 1) d = 0;
        if (d > 25) d = 0;
        if (argc >= 4) {
            sprintf(dataname, "%.98s", argv[3]);
        } else {
            sprintf(dataname, ".%04d%02d.txt", y, d);

Modified aoc2024.c from [c69db65f02] to [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

Modified aocutils.c from [9c6f5027fe] to [4e3d9f66a2].

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <stdio.h>
#include <stdlib.h>
#include "aocutils.h"

int text2array(int **dst, const char *r) {
    int *a = malloc(sizeof *a);
    int na = 0, sa = 1;
    char *err;
    int v;
    for (;;) {
        if (na == sa) {
            int *tmp = realloc(a, (size_t)(2*sa)*sizeof *tmp);
            if (!tmp) exit(EXIT_FAILURE);
            a = tmp;
            sa *= 2;
        }
        v = (int)strtol(r, &err, 10);
        a[na++] = v;
        if (!*err) break;
        r = err;
    }
    *dst = a;
    return na;
}






|




|




|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <stdio.h>
#include <stdlib.h>
#include "aocutils.h"

int text2array(int **dst, const char *r) {
    int *a = malloc(sizeof *a);
    size_t na = 0, sa = 1;
    char *err;
    int v;
    for (;;) {
        if (na == sa) {
            int *tmp = realloc(a, (2*sa) * sizeof *tmp);
            if (!tmp) exit(EXIT_FAILURE);
            a = tmp;
            sa *= 2;
        }
        v = strtol(r, &err, 10);
        a[na++] = v;
        if (!*err) break;
        r = err;
    }
    *dst = a;
    return na;
}
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
    size_t r = 0;
    while ((ch = fgetc(h)) != EOF) {
        if (r == s) {
            //grow tmp
            char *ttmp = realloc(tmp, (13*s)/8); // 13/8 is within 0.5% of the golden ratio
            if (ttmp) {
                tmp = ttmp;
                s = (13*s)/8;
            } else {
                free(tmp);
                return 0;
            }
        }
        tmp[r++] = (char)ch;
    }
    fclose(h);
    *dst = tmp;

    return r;
}








|





|







40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
    size_t r = 0;
    while ((ch = fgetc(h)) != EOF) {
        if (r == s) {
            //grow tmp
            char *ttmp = realloc(tmp, (13*s)/8); // 13/8 is within 0.5% of the golden ratio
            if (ttmp) {
                tmp = ttmp;
                s = (13*s) / 8;
            } else {
                free(tmp);
                return 0;
            }
        }
        tmp[r++] = ch;
    }
    fclose(h);
    *dst = tmp;

    return r;
}