aocc22

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

common.c (2157B)


      1 #include "common.h"
      2 
      3 #define swap(x, y) (x ^= y ^= x ^= y)
      4 
      5 static inline void invertstacks(stack_u64 **stacks, size_t nstacks) {
      6   size_t i, k, l;
      7   stack_u64 *ss = *stacks;
      8   for (i = 0; i < nstacks; i++) {
      9     k = 0;
     10     l = ss[i].nmemb - 1;
     11     while (k < l) {
     12       swap(ss[i].data[k], ss[i].data[l]);
     13       k++;
     14       l--;
     15     }
     16   }
     17 }
     18 
     19 void makeamove(stack_u64 *stacks, size_t nstacks, uint64_t *move) {
     20   uint64_t f = move[1], t = move[2], n = move[0];
     21   assert(f < nstacks);
     22   assert(t < nstacks);
     23   assert(n <= stacks[f].nmemb);
     24   size_t i;
     25   for (i = stacks[f].nmemb - n; i < stacks[f].nmemb; i++)
     26     stack_u64_push(&stacks[t], stacks[f].data[i]);
     27   stacks[f].nmemb -= n;
     28 }
     29 
     30 void printtops(stack_u64 *stacks, size_t nstacks) {
     31   size_t i;
     32   for (i = 0; i < nstacks; i++)
     33     printf("%c", (char)stack_u64_getlast(&stacks[i]));
     34 }
     35 
     36 void parse(stack_u64 *moves, stack_u64 **stacks, size_t *nstacks, char **lines,
     37            size_t nlines) {
     38   int hasstacks = 0;
     39   size_t nalloc_stacks = 128;
     40   size_t ninitd_stacks = 0;
     41   *stacks = calloc(nalloc_stacks, sizeof(**stacks));
     42   stack_u64_init(moves);
     43 
     44   size_t r, i;
     45   for (r = 0; r < nlines; r++) {
     46     char *line = lines[r];
     47     if (strlen(line) > 0 && line[1] == '1') {
     48       hasstacks = 1;
     49       *nstacks = ninitd_stacks;
     50       invertstacks(stacks, *nstacks);
     51     }
     52 
     53     if (!hasstacks) {
     54       for (i = 1; i < strlen(line); i += 4) {
     55         size_t j = i >> 2;
     56         while (j + 1 > ninitd_stacks) {
     57           if (ninitd_stacks >= nalloc_stacks) {
     58             nalloc_stacks <<= 1;
     59             *stacks = realloc(*stacks, nalloc_stacks * sizeof(**stacks));
     60           }
     61           stack_u64_init(&(*stacks)[ninitd_stacks]);
     62           ninitd_stacks++;
     63         }
     64 
     65         if (line[i] != ' ')
     66           stack_u64_push(&(*stacks)[j], (uint64_t)line[i]);
     67       }
     68     } else {
     69       if (strlen(line) > 0 && line[0] == 'm') {
     70         char *p;
     71         uint64_t rn;
     72         p = sread_next_u64(&rn, line);
     73         stack_u64_push(moves, rn);
     74         p = sread_next_u64(&rn, p);
     75         stack_u64_push(moves, rn - 1);
     76         p = sread_next_u64(&rn, p);
     77         stack_u64_push(moves, rn - 1);
     78       }
     79     }
     80   }
     81 }