Index: aoc.c ================================================================== --- aoc.c +++ aoc.c @@ -6,26 +6,26 @@ #include "aocdailies.h" // prototypes for all aocYYYYdd functions! #define MAX_YEAR 2024 int main(int argc, char **argv) { - int y = 0, d = 0; + unsigned y = 0, d = 0; char dataname[99]; if (argc >= 3) { char *err; - y = strtol(argv[1], &err, 10); + y = strtoul(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); + 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, ".%04d%02d.txt", y, d); + 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); Index: aoc2024.c ================================================================== --- aoc2024.c +++ aoc2024.c @@ -1,15 +1,17 @@ #include +#include +#include #include #include #include #include "aocutils.h" void aoc202403(char *data, size_t len) { (void)len; // unused argument - int sumproducts = 0, sumproducts2 = 0, term[2]; + 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()"); @@ -27,15 +29,15 @@ dontrite = strstr(dontrite + 1, "don't()"); } rest = mul + 4; if (isdigit((unsigned char)rest[0])) { char *err; - term[0] = strtol(rest, &err, 10); + term[0] = strtoul(rest, &err, 10); if (*err == ',') { if (isdigit((unsigned char)err[1])) { rest = err + 1; - term[1] = strtol(rest, &err, 10); + 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; @@ -45,61 +47,65 @@ } } 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; + 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 - int safe = 0, safe2 = 0; + unsigned safe = 0, safe2 = 0; char *line = strtok(data, "\n"); while (line) { - int *arr = NULL; - int narr = text2array(&arr, line); + unsigned *arr = NULL; + size_t narr = text2array(&arr, line); if (safereport(arr, narr)) { safe += 1; safe2 += 1; } else { - safe2 += safereportdamp(arr, narr); + safe2 += safereportdamp(arr, narr) ? 1 : 0; } 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); + 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) { - return *(const int *)a - *(const int *)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 @@ -138,15 +144,15 @@ 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 + 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 = (unsigned)(idxr - idxl + 1); // number of repeats in list2 + 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 Index: aocdailies.c ================================================================== --- aocdailies.c +++ aocdailies.c @@ -1,9 +1,9 @@ #include #include "aocdailies.h" -aocfunc *aocselect(int y, int d) { +aocfunc *aocselect(unsigned y, unsigned d) { aocfunc *p; switch (y * 100 + d) { default: p = NULL; break; case 202403: p = aoc202403; break; Index: aocdailies.h ================================================================== --- aocdailies.h +++ aocdailies.h @@ -2,11 +2,11 @@ #define AOCDAILIES_H_INCLUDED #include typedef void aocfunc(char *, size_t); -aocfunc *aocselect(int, int); +aocfunc *aocselect(unsigned, unsigned); aocfunc aoc202403; aocfunc aoc202402; aocfunc aoc202401; Index: aocutils.c ================================================================== --- aocutils.c +++ aocutils.c @@ -1,22 +1,23 @@ #include #include #include "aocutils.h" -int text2array(int **dst, const char *r) { - int *a = malloc(sizeof *a); - size_t na = 0, sa = 1; +size_t text2array(unsigned **dst, const char *r) { + unsigned *a = malloc(512 * sizeof *a); + size_t na = 0, sa = 512; char *err; - int v; + unsigned v; for (;;) { if (na == sa) { - int *tmp = realloc(a, (2*sa) * sizeof *tmp); + // 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 *= 2; + sa = (13*sa) / 8; } - v = strtol(r, &err, 10); + v = strtoul(r, &err, 10); a[na++] = v; if (!*err) break; r = err; } *dst = a; @@ -39,11 +40,12 @@ 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 + // 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); @@ -56,64 +58,29 @@ *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; +unsigned distance(unsigned a, unsigned b) { + if (a > b) return a - b; + return b - a; } -double fmax3(double a, double b, double c) { +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; } -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) { +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; } Index: aocutils.h ================================================================== --- aocutils.h +++ aocutils.h @@ -1,13 +1,10 @@ #ifndef AOCUTILS_H_INCLUDED #define AOCUTILS_H_INCLUDED -int text2array(int **dst, const char *r); +size_t text2array(unsigned **dst, const char *txt); 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); +unsigned distance(unsigned a, unsigned b); +unsigned max3u(unsigned a, unsigned b, unsigned c); +unsigned min3u(unsigned a, unsigned b, unsigned c); #endif