aocc23

Advent of Code 2023
git clone git://www.tkruger.se/aocc23.git
Log | Files | Refs | README

uppga.c (1748B)


      1 #include "common.h"
      2 
      3 static inline size_t parse_next(uint64_t **rows, size_t *nrows, uint64_t **cols,
      4                                 size_t *ncols, char **lines, size_t nlines,
      5                                 size_t s) {
      6   size_t i, j;
      7   size_t nc = strlen(lines[s]) - 1;
      8 
      9   // find number of rows
     10   size_t nr = 0;
     11   while (s + nr < nlines &&
     12          (lines[s + nr][0] == '.' || lines[s + nr][0] == '#')) {
     13     nr++;
     14   }
     15 
     16   // read rows
     17   uint64_t *r = malloc(nr * sizeof(*r));
     18   for (i = 0; i < nr; i++) {
     19     // read row i
     20     r[i] = 0;
     21     for (j = 0; j < nc; j++) {
     22       r[i] <<= 1;
     23       if (lines[s + i][j] == '#') {
     24         r[i] += 1;
     25       }
     26     }
     27   }
     28 
     29   // read cols
     30   uint64_t *c = malloc(nc * sizeof(*r));
     31   for (i = 0; i < nc; i++) {
     32     c[i] = 0;
     33     for (j = 0; j < nr; j++) {
     34       c[i] <<= 1;
     35       if (lines[s + j][i] == '#') {
     36         c[i] += 1;
     37       }
     38     }
     39   }
     40 
     41   // output
     42   *rows = r;
     43   *cols = c;
     44   *nrows = nr;
     45   *ncols = nc;
     46 
     47   return nr + 1;
     48 }
     49 
     50 static inline int is_refl(uint64_t *v, size_t nv, int i) {
     51   int j = i + 1;
     52 
     53   while (0 <= i && j < (int)nv) {
     54     if (v[i] != v[j])
     55       return 0;
     56     i--;
     57     j++;
     58   }
     59 
     60   return 1;
     61 }
     62 
     63 int main(int argc, char **argv) {
     64   char **lines;
     65   size_t i;
     66   size_t nlines = readlines(&lines, "input");
     67 
     68   size_t cr = 0;
     69   uint64_t summa = 0;
     70   uint64_t *rows, *cols;
     71   size_t nrows, ncols;
     72   while (cr < nlines) {
     73     cr += parse_next(&rows, &nrows, &cols, &ncols, lines, nlines, cr);
     74 
     75     for (i = 0; i < nrows - 1; i++) {
     76       if (is_refl(rows, nrows, (int)i))
     77         summa += 100 * (i + 1);
     78     }
     79 
     80     for (i = 0; i < ncols - 1; i++) {
     81       if (is_refl(cols, ncols, (int)i))
     82         summa += (i + 1);
     83     }
     84 
     85     free(rows);
     86     free(cols);
     87   }
     88 
     89   printf("%llu\n", summa);
     90 }