Index: aoc2024.c ================================================================== --- aoc2024.c +++ aoc2024.c @@ -7,10 +7,11 @@ #include "aocdailies.h" #include "aocutils.h" /* === aoc202407 ======================================================= Part one looks easy + Part two also easy ===================================================================== */ static unsigned long long concat(unsigned long long a, unsigned long long b) { unsigned long long r = a, t = b; while (b) { @@ -18,33 +19,29 @@ b /= 10; } return r + t; } -static bool canbetrue(unsigned long long v, unsigned long long *a, size_t n) { - if (n == 1) return (v == *a); - unsigned long long tmp = a[1]; - a[1] = a[0] + tmp; - if (canbetrue(v, a+1, n-1)) { a[1] = tmp; return true; } - a[1] = a[0] * tmp; - if (canbetrue(v, a+1, n-1)) { a[1] = tmp; return true; } - a[1] = tmp; - return false; -} - -static bool canbetrue3(unsigned long long v, unsigned long long *a, size_t n) { - // still, let's assume no unsigned long long overflowing - if (n == 1) return (v == *a); - unsigned long long tmp = a[1]; - a[1] = a[0] + tmp; - if (canbetrue3(v, a+1, n-1)) { a[1] = tmp; return true; } - a[1] = a[0] * tmp; - if (canbetrue3(v, a+1, n-1)) { a[1] = tmp; return true; } - a[1] = concat(a[0], tmp); - if (canbetrue3(v, a+1, n-1)) { a[1] = tmp; return true; } - a[1] = tmp; - return false; +static int operatorsrequired(unsigned long long v, unsigned long long *a, size_t n, int minop) { + // assumes no unsigned long long overflowing + if (n == 1) { + if (v == *a) return minop; + return 0; + } + unsigned long long tmp = a[1]; + a[1] = a[0] + tmp; + int p = operatorsrequired(v, a+1, n-1, (minop > 2)?3:2); + a[1] = tmp; + if (p) return p; + a[1] = a[0] * tmp; + p = operatorsrequired(v, a+1, n-1, (minop > 2)?3:2); + a[1] = tmp; + if (p) return p; + a[1] = concat(a[0], tmp); + p = operatorsrequired(v, a+1, n-1, 3); + a[1] = tmp; + return p; } void aoc202407(char *data, size_t len) { (void)len; // unused argument unsigned long long calibrationtotal = 0, calibration3total = 0; @@ -56,16 +53,25 @@ err += 1; // skip ':' nnumber = 0; while (*err == ' ') { number[nnumber++] = strtoul(err, &err, 10); } + switch (operatorsrequired(testvalue, number, nnumber, 0)) { + default: break; + case 2: calibrationtotal += testvalue; + __attribute__((fallthrough)); + case 3: calibration3total += testvalue; + break; + } + #if 0 if (canbetrue(testvalue, number, nnumber)) { calibrationtotal += testvalue; } if (canbetrue3(testvalue, number, nnumber)) { calibration3total += testvalue; } + #endif line = strtok(NULL, "\n"); } printf("The calibration total is {%llu}.\n", calibrationtotal); printf("The calibration total with three operators is {%llu}.\n", calibration3total); } @@ -107,11 +113,11 @@ switch (data[linearize2d(size, (unsigned)(row_pos+deltarow), (unsigned)(col_pos+deltacol))]) { default: exit(EXIT_FAILURE); // does not happen case '#': rightturn(&deltarow, &deltacol); break; case '.': visited++; data[linearize2d(size, (unsigned)(row_pos+deltarow), (unsigned)(col_pos+deltacol))] = 'X'; - /*fallthrough*/ + __attribute__((fallthrough)); case 'X': row_pos += deltarow; col_pos += deltacol; break; } } @@ -134,11 +140,11 @@ case '#': if (data[linearize2d(size, (unsigned)(row_pos), (unsigned)(col_pos))] == '4') looping = true; rightturn(&deltarow, &deltacol); break; case '4': looping = true; break; case '.': data[linearize2d(size, (unsigned)(row_pos+deltarow), (unsigned)(col_pos+deltacol))] = '0'; - /*fallthrough*/ + __attribute__((fallthrough)); case '1': case '2': case '3': data[linearize2d(size, (unsigned)(row_pos+deltarow), (unsigned)(col_pos+deltacol))]++; row_pos += deltarow; col_pos += deltacol;