Day 17 part 2: C

This commit is contained in:
2021-07-16 22:54:03 +02:00
parent 1d9edb73c1
commit 33c5cde0a4
3 changed files with 183 additions and 8 deletions

View File

@@ -22,7 +22,7 @@ ex1:
ex2:
@$(TIME) ex2.bash < $(INPUT) 2>&1
@#$(TIME) ex1-c 30000000 < $(INPUT) 2>&1
@$(TIME) ex2-c < $(INPUT) 2>&1
clean:
@rm -f ex1-c ex2-c core

View File

@@ -1,15 +1,20 @@
ex1-v1.bash : res=263
time: 1:28.00 real, 62.50 user, 31.11 sys
context-switch: 5860+165603, page-faults: 0+7574999
time: 1:47.86 real, 74.63 user, 39.28 sys
context-switch: 6224+166221, page-faults: 0+7568225
ex1.bash : res=263
time: 0:00.37 real, 0.37 user, 0.00 sys
context-switch: 5+1, page-faults: 0+321
time: 0:00.37 real, 0.36 user, 0.00 sys
context-switch: 1+1, page-faults: 0+322
ex1-c : res=263
time: 0:00.00 real, 0.00 user, 0.00 sys
context-switch: 0+1, page-faults: 0+149
context-switch: 0+1, page-faults: 0+150
ex2.bash : res=1680
time: 0:06.50 real, 6.43 user, 0.03 sys
context-switch: 52+14, page-faults: 0+2873
time: 0:06.47 real, 6.47 user, 0.00 sys
context-switch: 23+1, page-faults: 0+2852
ex2-c : res=1680
time: 0:00.00 real, 0.00 user, 0.00 sys
context-switch: 0+1, page-faults: 0+1634

170
day17/ex2-c.c Normal file
View File

@@ -0,0 +1,170 @@
/* ex1-c: Advent2020 game, day 17/game 2
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <stddef.h>
#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][SIZE];
#define CUBEZERO cube[0][0][0][0]
#define CUBE2X(cell) (((cell)-&CUBEZERO)/SIZE/SIZE/SIZE)
#define CUBE2Y(cell) (((cell)-&CUBEZERO)/SIZE/SIZE%SIZE)
#define CUBE2Z(cell) (((cell)-&CUBEZERO)/SIZE%SIZE)
#define CUBE2W(cell) (((cell)-&CUBEZERO)%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;
}
static void reset_cube()
{
int i, j, k, l;
for (i=0; i<SIZE; ++i)
for (j=0; j<SIZE; ++j)
for (k=0; k<SIZE; ++k)
for (l=0; l<SIZE; ++l)
reset_cell(&cube[i][j][k][l]);
}
static int count_active()
{
struct list_head *p;
int i=0;
list_for_each(p, &qset) {
++i;
}
return i;
}
static void init_row(char *line, int row)
{
int i, x, y, z, w;
static int ncols=0;
CELL *pcell;
if (ncols == 0)
ncols=strlen(line)-1;
y=ZERO-ncols/2+row;
z=ZERO;
w=ZERO;
for (i=0; *line; ++i, ++line) {
x=ZERO+i-ncols/2;
pcell=&cube[x][y][z][w];
if (*line == '#') {
list_add(&pcell->set, &qset);
list_add(&pcell->viewed, &qviewed);
pcell->state=ACTIVE;
pcell->visited=1;
}
}
}
void run_life()
{
struct cell *pcell, *ptmp;
int x, y, z, w, x1, y1, z1, w1;
/* 1) count +1 for neighbors */
list_for_each_entry(pcell, &qset, set) {
x=CUBE2X(pcell);
y=CUBE2Y(pcell);
z=CUBE2Z(pcell);
w=CUBE2W(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++) {
for (w1=w-1; w1<=w+1; w1++) {
if ((x1!=x || y1!=y || z1!=z || w1!=w)) {
ptmp=&cube[x1][y1][z1][w1];
++ptmp->count;
if (!ptmp->visited) {
list_add(&ptmp->viewed, &qviewed);
ptmp->visited=1;
}
}
}
}
}
}
}
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);
}
}
}
int main(ac, av)
int ac;
char **av;
{
char line[16];
int nline=0;
reset_cube();
INIT_LIST_HEAD(&qset);
INIT_LIST_HEAD(&qviewed);
while (fgets(line, sizeof line, stdin)) {
init_row(line, nline);
nline++;
}
for (int i=0; i<LOOPS; ++i)
run_life();
printf("%s : res=%d\n", *av, count_active());
exit (0);
}