From 1386061fbc72919f22cf018acb0ad6bf378f3010 Mon Sep 17 00:00:00 2001 From: Bruno Raoult Date: Fri, 16 Jul 2021 20:50:14 +0200 Subject: [PATCH] day 10 / C part 1 (tons of debug code) --- day17/Makefile | 2 +- day17/ex1-c.c | 428 +++++++++++++++++++++++++++++++++++++++++++++++++ day17/list.h | 165 +++++++++++++++++++ 3 files changed, 594 insertions(+), 1 deletion(-) create mode 100644 day17/ex1-c.c create mode 100644 day17/list.h diff --git a/day17/Makefile b/day17/Makefile index 2678d58..253c782 100644 --- a/day17/Makefile +++ b/day17/Makefile @@ -18,7 +18,7 @@ compile: ex1-c ex2-c ex1: @$(TIME) ex1-v1.bash < $(INPUT) 2>&1 @$(TIME) ex1.bash < $(INPUT) 2>&1 - @#$(TIME) ex1-c 2020 < $(INPUT) 2>&1 + @$(TIME) ex1-c < $(INPUT) 2>&1 ex2: @$(TIME) ex2.bash < $(INPUT) 2>&1 diff --git a/day17/ex1-c.c b/day17/ex1-c.c new file mode 100644 index 0000000..2ab5873 --- /dev/null +++ b/day17/ex1-c.c @@ -0,0 +1,428 @@ +/* ex1-c: Advent2020 game, day 17/game 1 + */ + +#include +#include +#include +#include +#include +#include "list.h" + +#define LOOPS 6 +#define MAXINIT 8 +#define SIZE ((2*LOOPS)+MAXINIT) +#define ZERO (SIZE/2) + +#define ACTIVE '#' +#define INACTIVE '.' + +typedef struct cell { + char state; + char oldstate; + bool visited; /* redundant ? */ + unsigned count; /* active neighbors */ + // for runs, we don't care unused cells + struct list_head set; /* current actives */ + struct list_head viewed; /* current visited */ +} CELL; + +LIST_HEAD(qset); +LIST_HEAD(qviewed); + +static CELL cube[SIZE][SIZE][SIZE]; + +#define R(x) ((x)+ROOT) +#define SET(pcell,x,y,z) (pcell[R(x)]= +#define CUBE2X(cell) (((cell)-&cube[0][0][0])/SIZE/SIZE) +#define CUBE2Y(cell) (((cell)-&cube[0][0][0])/SIZE%SIZE) +#define CUBE2Z(cell) (((cell)-&cube[0][0][0])/(SIZE/SIZE)%SIZE) + +#define HEADRESET(elt) { \ + (elt)->next=POISON_POINTER1;(elt)->prev=POISON_POINTER1; } + + +static void reset_cell(CELL *pcell) +{ + pcell->state=INACTIVE; + pcell->oldstate=INACTIVE; + pcell->visited=false; + pcell->count=0; + //HEADRESET(&pcell->set); + //HEADRESET(&pcell->viewed); +} +static void reset_cube() +{ + int i, j, k; + + for (i=0; istate != ACTIVE) + printf("cell (%ld,%ld,%ld): state is not ACTIVE.\n", + CUBE2X(pos), CUBE2Y(pos), CUBE2Z(pos)); + if (pos->visited != 1) + printf("cell (%ld,%ld,%ld): state is not VISITED.\n", + CUBE2X(pos), CUBE2Y(pos), CUBE2Z(pos)); + } + for (x=0; xstate, p->visited, p->count); + +} +static void set_print_cell(struct list_head *p) +{ + print_cell(list_entry(p, CELL, set)); +} +static void viewed_print_cell(struct list_head *p) +{ + print_cell(list_entry(p, CELL, viewed)); +} +static void print_cube() +{ + int x, y, z; + + for (z=0; zset, pos->set.prev, pos->set.next, + CUBE2X(pos), CUBE2Y(pos), CUBE2Z(pos)); + } +} +void print_viewed() +{ + struct cell *pos; + printf("viewed: %p n=%p p=%p\n", &qviewed, qviewed.next, qviewed.prev); + list_for_each_entry(pos, &qviewed, viewed) { + printf(" %p: %p %p\n", &pos->viewed, pos->viewed.prev, pos->viewed.next); + } +} + +static int count_active() +{ + struct list_head *p; + int i=0; + + list_for_each(p, &qset) { + ++i; + } + return i; +} +/* fill initial plane */ +static void add_row(char *line, int row) +{ + int i, x, y, z; + static int ncols=0; + CELL *pcell; + + printf("LINE %d: %lu %s\n", row, strlen(line)-1, line); + if (ncols == 0) + ncols=strlen(line)-1; + y=ZERO-ncols/2+row; + z=ZERO; + + for (i=0; *line; ++i, ++line) { + x=ZERO+i-ncols/2; + pcell=&cube[x][y][z]; + printf("pos=(%d,%d,%d): %#x ", x, y, z, *line); + printf(" --> (%ld, %ld, %ld)\n", CUBE2X(pcell), + CUBE2Y(pcell), CUBE2Z(pcell)); + if (*line == '#') { + list_add(&pcell->set, &qset); + list_add(&pcell->viewed, &qviewed); + pcell->state=ACTIVE; + pcell->visited=1; + //print_set(); + } + } +} + +void run_life() +{ + struct cell *pcell, *ptmp; + int x, y, z, x1, y1, z1; + + /* 1) count +1 for neighbors */ + list_for_each_entry(pcell, &qset, set) { + x=CUBE2X(pcell); + y=CUBE2Y(pcell); + z=CUBE2Z(pcell); + for (x1=x-1; x1<=x+1; x1++) { + for (y1=y-1; y1<=y+1; y1++) { + for (z1=z-1; z1<=z+1; z1++) { + if ((x1!=x || y1!=y || z1!=z)) { + ptmp=&cube[x1][y1][z1]; + ++ptmp->count; + if (!ptmp->visited) { + list_add(&ptmp->viewed, &qviewed); + ptmp->visited=1; + } + } + } + } + } + } + /*print_set(); + print_viewed();*/ + /* 2) apply rules for all visited cells */ + list_for_each_entry_safe(pcell, ptmp, &qviewed, viewed) { + switch (pcell->state) { + case ACTIVE: + if (pcell->count != 2 && pcell->count != 3) { + list_del(&pcell->set); + pcell->state=INACTIVE; + pcell->visited=0; + } + break; + case INACTIVE: + if (pcell->count == 3) { + list_add(&pcell->set, &qset); + pcell->state=ACTIVE; + pcell->visited=1; + } + break; + } + pcell->count=0; + if (pcell->state == INACTIVE) { + pcell->visited=0; + list_del(&pcell->viewed); + } + } + printf("active cells:\n"); + list_for_each_entry(pcell, &qset, set) { + print_cell(pcell); + } + printf("viewed cells:\n"); + list_for_each_entry(pcell, &qviewed, viewed) { + print_cell(pcell); + } + check_cube_sanity(); +} + +int main(ac, av) + int ac; + char **av; +{ + char line[16]; + int nline=0; + + reset_cube(); + INIT_LIST_HEAD(&qset); + INIT_LIST_HEAD(&qviewed); + printf("set: %p n=%p p=%p\n", &qset, qset.next, qset.prev); + printf("vis: %p n=%p p=%p\n", &qviewed, qviewed.next, qviewed.prev); + while (fgets(line, sizeof line, stdin)) { + add_row(line, nline); + nline++; + } + for (int i=0; ilast; + unsigned ncols=plane->ncol; + struct seats *ptr=plane->seats; + + for (i=0; i0 && !(i%ncols)) { + putchar('\n'); + } + printf("%2d ", (ptr+i)->neighbours); + } + putchar('\n'); +} + +void print_seats(plane) + struct plane *plane; +{ + unsigned i, psize=plane->last; + unsigned ncols=plane->ncol, nrow=plane->nrow; + struct seats *ptr=plane->seats; + + fprintf(stderr, "PLANE: address=%p seat=%p rows=%d cols=%d size=%d\n", + plane, ptr, nrow, ncols, psize); + for (i=0; i0 && !(i%ncols)) { + putchar('\n'); + } + printf("%c ", (ptr+i)->status); + } + putchar('\n'); +} + +void reset_seats(plane) + struct plane *plane; +{ + unsigned i, last=plane->last; + struct seats *seat=plane->seats; + + for (i=0; ineighbours=0; +} + +struct plane *add_row(plane, c) + struct plane *plane; + char *c; +{ + unsigned size; + + if (!plane) { + plane=malloc(sizeof(struct plane)); + plane->seats=malloc(sizeof(struct seats)*BLOCKSIZE); + plane->size=BLOCKSIZE; + plane->ncol=strlen(c)-1; + plane->last=0; + } + size=plane->size; + + while (*c) { + if (*c != '\n') { + if (plane->last == size) { + size+=BLOCKSIZE; + plane->size=size; + plane->seats=realloc(plane->seats, sizeof(struct seats)*size); + } + plane->seats[plane->last].status=*c; + plane->last++; + plane->nrow=plane->last/plane->ncol; + } + c++; + } + //sscanf(line, "%d", &val); + + return plane; +} + +int sit(plane) + struct plane *plane; +{ + unsigned changed=0, cur, seated=0; + unsigned last=plane->last; + struct seats *seats=plane->seats; + + for (cur=0; cur= 4) { + seats[cur].status='L'; + changed++; + } else { + seated++; + } + break; + case 'L': + if (seats[cur].neighbours == 0) { + seats[cur].status='#'; + changed++; + seated++; + } + break; + } + } + plane->seated=seated; + return changed; +} + +int calc(plane) + struct plane *plane; +{ + unsigned row, col, cur; + unsigned last=plane->last; + unsigned cols=plane->ncol; + unsigned rows=plane->nrow; + struct seats *seats=plane->seats; + + for (cur=0; cur 0) { + seats[cur - cols].neighbours++; + if (col > 0) + seats[cur - cols - 1].neighbours++; + if (col < (cols-1)) + seats[cur - cols + 1].neighbours++; + } + if (col > 0) { + seats[cur - 1].neighbours++; + if (row < (rows-1)) + seats[cur + cols - 1].neighbours++; + } + if (col < (cols-1)) { + seats[cur + 1].neighbours++; + if (row < (rows-1)) + seats[cur + cols + 1].neighbours++; + } + if (row < (rows-1)) + seats[cur + cols].neighbours++; + } + } + return 1; +} +*/ diff --git a/day17/list.h b/day17/list.h new file mode 100644 index 0000000..cb2a36a --- /dev/null +++ b/day17/list.h @@ -0,0 +1,165 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* circular list management. + * + * inspired from kernel's + */ +#ifndef _BR_LIST_H +#define _BR_LIST_H + +#include + +#define POISON_POINTER1 ((void *) 0x1) +#define POISON_POINTER2 ((void *) 0x2) + +struct list_head { + struct list_head *next, *prev; +}; + +#define container_of(ptr, type, member) ({ \ + const typeof(((type *)0)->member) * __mptr = (ptr); \ + (type *)((char *)__mptr - offsetof(type, member)); }) + +#define LIST_HEAD(name) \ + struct list_head name = { &(name), &(name) } + +static inline void INIT_LIST_HEAD(struct list_head *list) +{ + list->next = list; + list->prev = list; +} + +static inline void __list_add(struct list_head *new, + struct list_head *prev, + struct list_head *next) +{ + next->prev = new; + new->next = next; + new->prev = prev; + prev->next = new; +} +static inline void __list_join(struct list_head * prev, struct list_head * next) +{ + next->prev = prev; + prev->next = next; +} +static inline void __list_del_entry(struct list_head *entry) +{ + __list_join(entry->prev, entry->next); +} + + +static inline void list_add(struct list_head *new, struct list_head *head) +{ + __list_add(new, head, head->next); +} + +static inline void list_add_tail(struct list_head *new, struct list_head *head) +{ + __list_add(new, head->prev, head); +} + +static inline void list_del(struct list_head *entry) +{ + __list_del_entry(entry); + entry->next = POISON_POINTER1; + entry->prev = POISON_POINTER1; +} + +static inline void list_replace(struct list_head *old, + struct list_head *new) +{ + new->next = old->next; + new->next->prev = new; + new->prev = old->prev; + new->prev->next = new; +} + +static inline void list_swap(struct list_head *entry1, + struct list_head *entry2) +{ + struct list_head *pos = entry2->prev; + + list_del(entry2); + list_replace(entry1, entry2); + if (pos == entry1) + pos = entry2; + list_add(entry1, pos); +} + +static inline int list_is_first(const struct list_head *list, + const struct list_head *head) +{ + return list->prev == head; +} + +static inline int list_is_last(const struct list_head *list, + const struct list_head *head) +{ + return list->next == head; +} + +static inline int list_empty(const struct list_head *head) +{ + return head->next == head; +} + +static inline int list_is_singular(const struct list_head *head) +{ + return !list_empty(head) && (head->next == head->prev); +} + +#define list_entry(ptr, type, member) \ + container_of(ptr, type, member) + +#define list_first_entry(ptr, type, member) \ + list_entry((ptr)->next, type, member) + +#define list_last_entry(ptr, type, member) \ + list_entry((ptr)->prev, type, member) + +#define list_first_entry_or_null(ptr, type, member) ({ \ + struct list_head *head__ = (ptr); \ + struct list_head *pos__ = READ_ONCE(head__->next); \ + pos__ != head__ ? list_entry(pos__, type, member) : NULL; \ + }) + +#define list_next_entry(pos, member) \ + list_entry((pos)->member.next, typeof(*(pos)), member) + +#define list_prev_entry(pos, member) \ + list_entry((pos)->member.prev, typeof(*(pos)), member) + +#define list_for_each(pos, head) \ + for (pos = (head)->next; pos != (head); pos = pos->next) + +#define list_for_each_continue(pos, head) \ + for (pos = pos->next; pos != (head); pos = pos->next) + +#define list_for_each_prev(pos, head) \ + for (pos = (head)->prev; pos != (head); pos = pos->prev) + +#define list_entry_is_head(pos, head, member) \ + (&pos->member == (head)) + +#define list_for_each_entry(pos, head, member) \ + for (pos = list_first_entry(head, typeof(*pos), member); \ + !list_entry_is_head(pos, head, member); \ + pos = list_next_entry(pos, member)) + +#define list_for_each_entry_safe(pos, n, head, member) \ + for (pos = list_first_entry(head, typeof(*pos), member), \ + n = list_next_entry(pos, member); \ + !list_entry_is_head(pos, head, member); \ + pos = n, n = list_next_entry(n, member)) + +#define list_for_each_entry_reverse(pos, head, member) \ + for (pos = list_last_entry(head, typeof(*pos), member); \ + !list_entry_is_head(pos, head, member); \ + pos = list_prev_entry(pos, member)) + +#define list_for_each_entry_continue_reverse(pos, head, member) \ + for (pos = list_prev_entry(pos, member); \ + !list_entry_is_head(pos, head, member); \ + pos = list_prev_entry(pos, member)) + +#endif /* _BR_LIST_H */