aocc22

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

common.c (3362B)


      1 #include "common.h"
      2 
      3 void printgd(gd *g) {
      4   size_t i, j;
      5   for (j = 0; j < g->maxy; j++) {
      6     for (i = 494; i < 504; i++) {
      7       uint8_t v = g->grid[i * g->h + j];
      8       if (v == 0)
      9         printf(".");
     10       else if (v == 1)
     11         printf("#");
     12       else
     13         printf("o");
     14     }
     15     printf("\n");
     16   }
     17 }
     18 
     19 int sandfall(gd *g) {
     20   size_t x = 500, y = 0;
     21 
     22   while (y < g->maxy) {
     23     assert(x > 0);
     24     if (g->grid[x * g->h + (y + 1)] == 0) {
     25       y++;
     26     } else if (g->grid[(x - 1) * g->h + (y + 1)] == 0) {
     27       x--;
     28       y++;
     29     } else if (g->grid[(x + 1) * g->h + (y + 1)] == 0) {
     30       x++;
     31       y++;
     32     } else {
     33       g->grid[x * g->h + y] = 2;
     34       if (x == 500 && y == 0)
     35         return 3;
     36       return 0;
     37     }
     38   }
     39   return 1;
     40 }
     41 
     42 gd *parse(char **lines, size_t nlines, int floor) {
     43   stack_u64 xs[nlines + 1], ys[nlines + 1];
     44   char *p;
     45   size_t i, j;
     46 
     47   uint64_t minx = UINT64_MAX, maxx = 0, miny = UINT64_MAX, maxy = 0;
     48 
     49   for (i = 0; i < nlines; i++) {
     50     stack_u64_init(&xs[i]);
     51     stack_u64_init(&ys[i]);
     52     uint64_t t;
     53     size_t c = 0;
     54     p = lines[i];
     55     while ((p = sread_next_u64(&t, p)) != NULL) {
     56       if (c % 2 == 0) {
     57         stack_u64_push(&xs[i], t);
     58         if (t < minx)
     59           minx = t;
     60         if (t > maxx)
     61           maxx = t;
     62       } else {
     63         stack_u64_push(&ys[i], t);
     64         if (t < miny)
     65           miny = t;
     66         if (t > maxy)
     67           maxy = t;
     68       }
     69       c++;
     70     }
     71   }
     72 
     73   if (floor) {
     74     maxy += 2;
     75     maxx += maxy + 1; // at most diagonal
     76     stack_u64_init(&xs[nlines]);
     77     stack_u64_init(&ys[nlines]);
     78     stack_u64_push(&xs[nlines], 0);
     79     stack_u64_push(&ys[nlines], maxy);
     80     stack_u64_push(&xs[nlines], maxx);
     81     stack_u64_push(&ys[nlines], maxy);
     82     nlines++;
     83   }
     84 
     85   assert(minx > 0); // otherwise we would have to shift
     86   assert(miny > 0);
     87 
     88   uint8_t *grid = calloc((maxx + 1) * (maxy + 1), sizeof(*grid));
     89 
     90   for (i = 0; i < nlines; i++) {
     91     assert(xs[i].nmemb == ys[i].nmemb);
     92     for (j = 0; j < xs[i].nmemb - 1; j++) {
     93       assert(xs[i].data[j] == xs[i].data[j + 1] ||
     94              ys[i].data[j] == ys[i].data[j + 1]);
     95       if (xs[i].data[j] == xs[i].data[j + 1]) {
     96         uint64_t x = xs[i].data[j];
     97         uint64_t yfrom = ys[i].data[j] < ys[i].data[j + 1] ? ys[i].data[j]
     98                                                            : ys[i].data[j + 1];
     99         uint64_t yto = ys[i].data[j] < ys[i].data[j + 1] ? ys[i].data[j + 1]
    100                                                          : ys[i].data[j];
    101         while (yfrom != yto) {
    102           grid[x * (maxy + 1) + yfrom] = 1;
    103           yfrom++;
    104         }
    105         grid[x * (maxy + 1) + yfrom] = 1;
    106       } else {
    107         uint64_t y = ys[i].data[j];
    108         uint64_t xfrom = xs[i].data[j] < xs[i].data[j + 1] ? xs[i].data[j]
    109                                                            : xs[i].data[j + 1];
    110         uint64_t xto = xs[i].data[j] < xs[i].data[j + 1] ? xs[i].data[j + 1]
    111                                                          : xs[i].data[j];
    112         while (xfrom != xto) {
    113           grid[xfrom * (maxy + 1) + y] = 1;
    114           xfrom++;
    115         }
    116         grid[xfrom * (maxy + 1) + y] = 1;
    117       }
    118     }
    119   }
    120 
    121   gd *r = malloc(sizeof(*r));
    122   r->h = (size_t)maxy + 1;
    123   r->w = (size_t)maxx + 1;
    124   r->minx = minx;
    125   r->miny = miny;
    126   r->maxx = maxx;
    127   r->maxy = maxy;
    128   r->grid = grid;
    129 
    130   return r;
    131 }