Advent of Code

Check-in [8e5f2a70ef]
Login

Check-in [8e5f2a70ef]

Overview
Comment:202401 and 202402, 4 stars
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 8e5f2a70efec8c27b0cbe99f5a2216abd04be7e8214e2670eae8c035ca016d9f
User & Date: nnz on 2024-12-02 20:04:24
Original Comment: day 1, day 2
Other Links: manifest | tags
Context
2024-12-02
20:53
moved big switch out of main check-in: dd0c03da2e user: nnz tags: trunk
20:04
202401 and 202402, 4 stars check-in: 8e5f2a70ef user: nnz tags: trunk
18:41
added license check-in: 1547ed2388 user: nnz tags: trunk
Changes

Added aoc.c version [afd38c9390].





























































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
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
#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 = (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);
        }
    }
    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");
        exit(EXIT_FAILURE);
    }
    // read data from dataname into input
    char *input = NULL;
    size_t ilen = slurp(&input, dataname);

    // call the right function
    void (*p)(char *, size_t) = NULL;
    switch (y * 100 + d) {
        default: fprintf(stderr, "no function for year %d and day %d\n", y, d);
                 exit(EXIT_FAILURE);
        #if 0
        case 201501: p = aoc201501; break;
        case 201502: p = aoc201502; break;
        case 201503: p = aoc201503; break;
        case 201504: p = aoc201504; break;
        case 201505: p = aoc201505; break;
        case 201506: p = aoc201506; break;
        case 201507: p = aoc201507; break;
        case 201508: p = aoc201508; break;
        case 201509: p = aoc201509; break;
        case 201510: p = aoc201510; break;
        case 201511: p = aoc201511; break;
        case 201512: p = aoc201512; break;
        case 201513: p = aoc201513; break;
        case 201514: p = aoc201514; break;
        case 201515: p = aoc201515; break;
        case 201516: p = aoc201516; break;
        case 201517: p = aoc201517; break;
        case 201518: p = aoc201518; break;
        case 201519: p = aoc201519; break;
        case 201520: p = aoc201520; break;
        case 201521: p = aoc201521; break;
        case 201522: p = aoc201522; break;
        case 201523: p = aoc201523; break;
        case 201524: p = aoc201524; break;
        case 201525: p = aoc201525; break;
        #endif

        case 202401: p = aoc202401; break;
        case 202402: p = aoc202402; break;
    }
    p(input, ilen);
    free(input);
}

Added aoc2024.c version [a9e75b1bd8].



































































































































































































































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

#include "aocutils.h"

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, [[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;
            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, [[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

Added aocdailies.h version [981e8d069f].







































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
#ifndef AOCDAILY_H_INCLUDED
#define AOCDAILY_H_INCLUDED

#if 0
void aoc201501(char *, size_t);
void aoc201502(char *, size_t);
void aoc201503(char *, size_t);
void aoc201504(char *, size_t);
void aoc201505(char *, size_t);
void aoc201506(char *, size_t);
void aoc201507(char *, size_t);
void aoc201508(char *, size_t);
void aoc201509(char *, size_t);
void aoc201510(char *, size_t);
void aoc201511(char *, size_t);
void aoc201512(char *, size_t);
void aoc201513(char *, size_t);
void aoc201514(char *, size_t);
void aoc201515(char *, size_t);
void aoc201516(char *, size_t);
void aoc201517(char *, size_t);
void aoc201518(char *, size_t);
void aoc201519(char *, size_t);
void aoc201520(char *, size_t);
void aoc201521(char *, size_t);
void aoc201522(char *, size_t);
void aoc201523(char *, size_t);
void aoc201524(char *, size_t);
void aoc201525(char *, size_t);
#endif

void aoc202401(char *, size_t);
void aoc202402(char *, size_t);

#endif

Added aocutils.c version [abd0f6ad4b].















































































































































































































































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

size_t slurp(char **dst, const char *fn) {
    if (*dst) {
        fprintf(stderr, "slurp() must be called with a pointer to void!\n");
        exit(EXIT_FAILURE);
    }
    FILE *h = fopen(fn, "r");
    if (!h) {
        perror(fn);
        exit(EXIT_FAILURE);
    }

    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);
            if (ttmp) {
                tmp = ttmp;
                s = (13*s)/8;
            } else {
                free(tmp);
                return 0;
            }
        }
        tmp[r++] = (char)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;
}

Added aocutils.h version [c366e35210].



























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