aocc22

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

common.c (2094B)


      1 #include "common.h"
      2 
      3 int compare(const lori *a, const lori *b) {
      4   if (a->head != NULL && b->head != NULL) {
      5     size_t i = 0;
      6     lori *af = SIMPLEQ_FIRST(a->head);
      7     lori *bf = SIMPLEQ_FIRST(b->head);
      8     while (af != NULL && bf != NULL) {
      9       int comp = compare(af, bf);
     10       if (comp != 0)
     11         return comp;
     12       af = SIMPLEQ_NEXT(af, entries);
     13       bf = SIMPLEQ_NEXT(bf, entries);
     14     }
     15     if (af != NULL)
     16       return 1;
     17     else if (bf != NULL)
     18       return -1;
     19     return 0;
     20   } else if (a->head != NULL || b->head != NULL) {
     21     int comp = 0;
     22     if (a->head != NULL) {
     23       lori *af = SIMPLEQ_FIRST(a->head);
     24       if (af == NULL)
     25         return -1;
     26       comp = compare(af, b);
     27       if (comp != 0)
     28         return comp;
     29       if (SIMPLEQ_NEXT(af, entries) == NULL)
     30         return 0;
     31       return 1;
     32     } else {
     33       lori *bf = SIMPLEQ_FIRST(b->head);
     34       if (bf == NULL)
     35         return 1;
     36       comp = compare(a, bf);
     37       if (comp != 0)
     38         return comp;
     39       if (SIMPLEQ_NEXT(bf, entries) == NULL)
     40         return 0;
     41       return -1;
     42     }
     43     return comp;
     44   }
     45   if (a->v < b->v) {
     46     return -1;
     47   } else if (b->v < a->v) {
     48     return 1;
     49   }
     50   return 0;
     51 }
     52 
     53 void printlori(const lori *x) {
     54   if (x->head != NULL) {
     55     printf("[");
     56     lori *np;
     57     SIMPLEQ_FOREACH(np, x->head, entries) { printlori(np); }
     58     printf("]");
     59   } else {
     60     printf("%llu,", x->v);
     61   }
     62 }
     63 
     64 lori *parseline(char *line, char **next) {
     65   if (line == NULL || line[0] == '\0') {
     66     next = NULL;
     67     return NULL;
     68   }
     69 
     70   lori *r = malloc(sizeof(*r));
     71 
     72   if ('0' <= line[0] && line[0] <= '9') {
     73     r->head = NULL;
     74     *next = sread_next_u64(&(r->v), line);
     75   } else if (line[0] == ',') {
     76     *next = line + 1;
     77     free(r);
     78     return NULL;
     79   } else {
     80     r->v = UINT64_MAX;
     81     r->head = malloc(sizeof(*r->head));
     82     SIMPLEQ_INIT(r->head);
     83 
     84     lori *e;
     85     line++;
     86     char *nn = &line[1];
     87     while (line[0] != ']') {
     88       e = parseline(line, &nn);
     89       if (e != NULL)
     90         SIMPLEQ_INSERT_TAIL(r->head, e, entries);
     91       line = nn;
     92     }
     93     *next = line + 1;
     94   }
     95 
     96   return r;
     97 }