Advent of Code

Check-in [fe9956e07d]
Login

Check-in [fe9956e07d]

Overview
Comment:use unsigned
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: fe9956e07dbde87a2e41be64478d0781e89eb004c8e07071d8b97ab1a473533b
User & Date: nnz on 2024-12-04 09:27:39
Other Links: manifest | tags
Context
2024-12-04
09:30
_XOPEN_SOURCE removed check-in: 38646cdd7a user: nnz tags: trunk
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
Changes

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

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
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "aocutils.h"
#include "aocdailies.h" // prototypes for all aocYYYYdd functions!

#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);
        }
    }
    if ((y == 0) || (d == 0)) {
        fprintf(stderr, "syntax: %s yyyy dd [input-file]\n", argv[0]);
        fprintf(stderr, "    where 2015 <= yyyy <= %d\n", MAX_YEAR);
        fprintf(stderr, "    and 1 <= dd <= 25\n");
        fprintf(stderr, "if no [input-file] is supplied loads the file .yyyydd.txt\n");










|



|



|






|







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
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "aocutils.h"
#include "aocdailies.h" // prototypes for all aocYYYYdd functions!

#define MAX_YEAR 2024

int main(int argc, char **argv) {
    unsigned y = 0, d = 0;
    char dataname[99];
    if (argc >= 3) {
        char *err;
        y = strtoul(argv[1], &err, 10);
        if (err && *err) y = 0;
        if (y < 2015) y = 0;
        if (y > MAX_YEAR) y = 0;
        d = strtoul(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, ".%04u%02u.txt", y, d);
        }
    }
    if ((y == 0) || (d == 0)) {
        fprintf(stderr, "syntax: %s yyyy dd [input-file]\n", argv[0]);
        fprintf(stderr, "    where 2015 <= yyyy <= %d\n", MAX_YEAR);
        fprintf(stderr, "    and 1 <= dd <= 25\n");
        fprintf(stderr, "if no [input-file] is supplied loads the file .yyyydd.txt\n");

Modified aoc2024.c from [57ed145cda] to [f495d3d009].

1


2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#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 (;;) {
        char *mul = strstr(rest, "mul(");

>
>








|







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
    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
            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;
                        }
                    }
                }
            }
        } else {
            break;
        }
    }
    printf("The sum of the products is {%d}.\n", sumproducts);
    printf("The sum of the products with conditionals is {%d}.\n", sumproducts2);
}

static int safereport(int *v, int 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;
        if (dir == -1) {
            if (v[k-1] < v[k]) return 0;
        } else {
            if (v[k-1] > v[k]) return 0;
        }
    }
    return 1;
}

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;
}

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;
            safe2 += 1;
        } else {
            safe2 += safereportdamp(arr, narr);
        }
        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);
}

static int delta(const void *a, const void *b) {




    return *(const int *)a - *(const int *)b;
}

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







|



|













|
|


|


|
|
|

|

|


|


|
|
|
|
|
|
|
|




|


|
|




|




|
|



>
>
>
>
|







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] = strtoul(rest, &err, 10);
                if (*err == ',') {
                    if (isdigit((unsigned char)err[1])) {
                        rest = err + 1;
                        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 {%u}.\n", sumproducts);
    printf("The sum of the products with conditionals is {%u}.\n", sumproducts2);
}

static bool safereport(unsigned *v, size_t nv) {
    int dir = 1;               // ascending
    if (v[0] > v[1]) dir = -1; // descending
    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 false;
        } else {
            if (v[k-1] > v[k]) return false;
        }
    }
    return true;
}

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
    unsigned safe = 0, safe2 = 0;
    char *line = strtok(data, "\n");
    while (line) {
        unsigned *arr = NULL;
        size_t narr = text2array(&arr, line);
        if (safereport(arr, narr)) {
            safe += 1;
            safe2 += 1;
        } else {
            safe2 += safereportdamp(arr, narr) ? 1 : 0;
        }
        free(arr);
        line = strtok(NULL, "\n");
    }
    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 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
    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++) {







|
|


|







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) {
            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 = 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++) {

Modified aocdailies.c from [ffaafe2cdb] to [b62593c7a5].

1
2
3
4
5
6
7
8
9
10
11
#include <stddef.h>
#include "aocdailies.h"

aocfunc *aocselect(int y, int d) {
    aocfunc *p;
    switch (y * 100 + d) {
        default: p = NULL; break;

        case 202403: p = aoc202403; break;
        case 202402: p = aoc202402; break;
        case 202401: p = aoc202401; break;



|







1
2
3
4
5
6
7
8
9
10
11
#include <stddef.h>
#include "aocdailies.h"

aocfunc *aocselect(unsigned y, unsigned d) {
    aocfunc *p;
    switch (y * 100 + d) {
        default: p = NULL; break;

        case 202403: p = aoc202403; break;
        case 202402: p = aoc202402; break;
        case 202401: p = aoc202401; break;

Modified aocdailies.h from [769a4a36e5] to [9b2b79b159].

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#ifndef AOCDAILIES_H_INCLUDED
#define AOCDAILIES_H_INCLUDED

#include <stddef.h>

typedef void aocfunc(char *, size_t);
aocfunc *aocselect(int, int);

aocfunc aoc202403;
aocfunc aoc202402;
aocfunc aoc202401;

#if 0
aocfunc aoc201525;






|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
#ifndef AOCDAILIES_H_INCLUDED
#define AOCDAILIES_H_INCLUDED

#include <stddef.h>

typedef void aocfunc(char *, size_t);
aocfunc *aocselect(unsigned, unsigned);

aocfunc aoc202403;
aocfunc aoc202402;
aocfunc aoc202401;

#if 0
aocfunc aoc201525;

Modified aocutils.c from [4e3d9f66a2] to [dc2d5534c7].

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;
}




|
|
|

|


>
|


|

|







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
#include <stdio.h>
#include <stdlib.h>
#include "aocutils.h"

size_t text2array(unsigned **dst, const char *r) {
    unsigned *a = malloc(512 * sizeof *a);
    size_t na = 0, sa = 512;
    char *err;
    unsigned v;
    for (;;) {
        if (na == sa) {
            // 13/8 is within 0.5% of the golden ratio
            unsigned *tmp = realloc(a, ((13*sa) / 8) * sizeof *tmp);
            if (!tmp) exit(EXIT_FAILURE);
            a = tmp;
            sa = (13*sa) / 8;
        }
        v = strtoul(r, &err, 10);
        a[na++] = v;
        if (!*err) break;
        r = err;
    }
    *dst = a;
    return na;
}
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
114
115
116
117
118
119
    int ch;
    char *tmp = malloc(512);
    size_t s = 512;
    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;
}

int max3(int a, int b, int c) {
    if (a > b) {
        if (a > c) return a;
        return c;
    } else {
        if (b > c) return b;
    }
    return c;
}

double fmax3(double a, double b, double c) {
    if (a > b) {
        if (a > c) return a;
        return c;
    } else {
        if (b > c) return b;
    }
    return c;
}

long max3l(long a, long b, long c) {
    if (a > b) {
        if (a > c) return a;
        return c;
    } else {
        if (b > c) return b;
    }
    return c;
}

int min3(int a, int b, int c) {
    if (a < b) {
        if (a < c) return a;
        return c;
    } else {
        if (b < c) return b;
    }
    return c;
}

double fmin3(double a, double b, double c) {
    if (a < b) {
        if (a < c) return a;
        return c;
    } else {
        if (b < c) return b;
    }
    return c;
}

long min3l(long a, long b, long c) {
    if (a < b) {
        if (a < c) return a;
        return c;
    } else {
        if (b < c) return b;
    }
    return c;
}







>
|
















|
|
<
|
<
<
|
<
|
|
<









<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<








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
    int ch;
    char *tmp = malloc(512);
    size_t s = 512;
    size_t r = 0;
    while ((ch = fgetc(h)) != EOF) {
        if (r == s) {
            //grow tmp
            // 13/8 is within 0.5% of the golden ratio
            char *ttmp = realloc(tmp, (13*s) / 8);
            if (ttmp) {
                tmp = ttmp;
                s = (13*s) / 8;
            } else {
                free(tmp);
                return 0;
            }
        }
        tmp[r++] = ch;
    }
    fclose(h);
    *dst = tmp;

    return r;
}

unsigned distance(unsigned a, unsigned b) {
    if (a > b) return a - b;

    return b - a;


}


unsigned max3u(unsigned a, unsigned b, unsigned c) {

    if (a > b) {
        if (a > c) return a;
        return c;
    } else {
        if (b > c) return b;
    }
    return c;
}










unsigned min3u(unsigned a, unsigned b, unsigned c) {





















    if (a < b) {
        if (a < c) return a;
        return c;
    } else {
        if (b < c) return b;
    }
    return c;
}

Modified aocutils.h from [c366e35210] to [b9fb3ba61b].

1
2
3
4
5
6
7
8
9
10
11
12
13
#ifndef AOCUTILS_H_INCLUDED
#define AOCUTILS_H_INCLUDED

int text2array(int **dst, const char *r);
size_t slurp(char **dst, const char *filename);
int max3(int a, int b, int c);
double fmax3(double a, double b, double c);
long max3l(long a, long b, long c);
int min3(int a, int b, int c);
double fmin3(double a, double b, double c);
long min3l(long a, long b, long c);

#endif



|

|
<
|
|
<
<


1
2
3
4
5
6

7
8


9
10
#ifndef AOCUTILS_H_INCLUDED
#define AOCUTILS_H_INCLUDED

size_t text2array(unsigned **dst, const char *txt);
size_t slurp(char **dst, const char *filename);
unsigned distance(unsigned a, unsigned b);

unsigned max3u(unsigned a, unsigned b, unsigned c);
unsigned min3u(unsigned a, unsigned b, unsigned c);



#endif