diff --git a/2020/day19/Makefile b/2020/day19/Makefile index b66bb2c..1916b07 100644 --- a/2020/day19/Makefile +++ b/2020/day19/Makefile @@ -39,26 +39,35 @@ CFLAGS += -march=native CFLAGS += -Wmissing-declarations CFLAGS += -Wno-unused-result -#CFLAGS += -DDEBUG_DEBUG # activate general debug (debug.c) -#CFLAGS += -DDEBUG_POOL # memory pools management +CFLAGS += -DDEBUG_DEBUG # activate general debug (debug.c) +CFLAGS += -DDEBUG_POOL # memory pools management + +VALGRIND := valgrind +VALGRINDFLAGS := --leak-check=full --show-leak-kinds=all --track-origins=yes \ + --sigill-diagnostics=yes --quiet --show-error-list=yes + TIME := \time -f "\ttime: %E real, %U user, %S sys\n\tcontext-switch:\t%c+%w, page-faults: %F+%R\n" export PATH := .:$(PATH) -.PHONY: clean all compile assembly memcheck memcheck1 memcheck2 ex1 ex2 bear +.PHONY: clean all compile assembly memcheck memcheck1 memcheck2 ex1 ex2 bear org -all: ex1 ex2 +org: README.org + +all: org ex1 ex2 memcheck: memcheck1 memcheck2 memcheck1: aoc-c - @valgrind -q -s --track-origins=yes aoc-c -p 1 < $(INPUT) + @$(VALGRIND) $(VALGRINDFLAGS) aoc-c -p 1 < $(INPUT) memcheck2: aoc-c - @valgrind -q -s --track-origins=yes aoc-c -p 2 < $(INPUT) + @$(VALGRIND) $(VALGRINDFLAGS) aoc-c -p 2 < $(INPUT) compile: aoc-c +cpp: aoc-c.i + assembly: aoc-c.s ex1: aoc-c @@ -70,7 +79,7 @@ ex2: aoc-c @$(TIME) aoc-c -p 2 < $(INPUT) 2>&1 clean: - @rm -f aoc-c core* vgcore* gmon.out aoc-c.s compile_commands.json + @rm -f aoc-c core* vgcore* gmon.out aoc-c.s aoc-c.i README.html compile_commands.json .c: @echo compiling $< diff --git a/2020/day24/Makefile b/2020/day24/Makefile index 4ff34ee..ea6e8f9 100644 --- a/2020/day24/Makefile +++ b/2020/day24/Makefile @@ -61,10 +61,11 @@ memcheck1: aoc-c memcheck2: aoc-c @$(VALGRIND) $(VALGRINDFLAGS) aoc-c -p 2 < $(INPUT) - @#@valgrind -s --track-origins=yes aoc-c -p 2 < $(INPUT) compile: aoc-c +cpp: aoc-c.i + assembly: aoc-c.s ex1: aoc-c @@ -99,3 +100,7 @@ clean: # generate compile_commands.json $(CCLSFILE): aoc-c.c Makefile $(BEAR) -- make clean compile + +bear: clean + @$(BEAR) -- make compile + @touch .ccls-root diff --git a/2020/day24/aoc-c.c b/2020/day24/aoc-c.c index d90a6eb..d246346 100644 --- a/2020/day24/aoc-c.c +++ b/2020/day24/aoc-c.c @@ -4,40 +4,171 @@ #include #include #include +#include +#include "bits.h" +#include "pool.h" +#include "debug.h" +#include "hashtable.h" +#include "debug.h" -int main(ac, av) - int ac; - char **av; +/* In day 24 tasks, we do not care the order of tiles, as we regenerate + * a new list after each process. + * So we will rely on a hashtable, which will allow to quickly find a + * given point. + */ +typedef union coord { + u64 val; + struct { + s32 x, y; + }; +} coord_t; + +typedef struct point { + coord_t pos; + struct hlist_node coll; /* entry in hash table */ + struct list_head all; +} point_t; + +#define HBITS 12 /* in bits: 12 bits = 4096 */ +#define HSIZE (1 << HBITS) + +DEFINE_HASHTABLE(hash1, HBITS); +DEFINE_HASHTABLE(hash2, HBITS); +struct hlist_head *cur = hash1, *next = hash2; + +pool_t *pt_pool; + +static __always_inline u32 hash(coord_t p) +{ + return hash_64(p.val, HBITS); +} + +static point_t *find_point(struct hlist_head *head, coord_t p) +{ + point_t *point; + hlist_for_each_entry(point, head, coll) { + if (point->pos.val == p.val) + return point; + } + return NULL; +} + +static point_t *add_point(struct hlist_head *p, coord_t pos) +{ + point_t *new; + u32 h; + + h = hash(pos); + if (!(new = find_point(p + h, pos))) { + new = pool_get(pt_pool); + new->pos.val = pos.val; + hlist_add_head(&new->coll, p + h); + } + return new; +} + +static point_t *flip_point(struct hlist_head *p, coord_t pos) +{ + point_t *new; + u32 h; + + log_f(3, "val=%lu x=%d y=%d ", pos.val, pos.x, pos.y); + h = hash(pos); + log(3, "hash=%d ", h); + if ((new = find_point(p + h, pos))) { + log(3, "removing tile\n"); + hlist_del(&new->coll); + pool_add(pt_pool, new); + new = NULL; + } else { + log(3, "adding tile\n"); + new = pool_get(pt_pool); + new->pos.val = pos.val; + hlist_add_head(&new->coll, p + h); + } + return new; +} + +static int count_points(struct hlist_head *h) +{ + point_t *cur; + int res = 0; + for (int bkt = 0; bkt < HSIZE; ++bkt) { + hlist_for_each_entry(cur, &h[bkt], coll) { + res++; + } + } + return res; +} + +static void parse() { size_t alloc; ssize_t len; char *buf = NULL; - while ((len = getline(&buf, &alloc, stdin))) { + while ((len = getline(&buf, &alloc, stdin)) > 0) { buf[len - 1] = 0; - int x=0, y=0; + coord_t p = { .val = 0 }; + puts(buf); char *c = buf; while (*c) { switch (*c) { case 'e': - ++x; + ++p.x; break; case 'w': - ++y; + --p.x; break; case 's': - --y, ++c; + --p.y; + ++c; break; case 'n': - ++y, ++c; + ++p.y; + ++c; } if (*c == 'e') - ++x; + ++p.x; else if (*c == 'w') - ++y; + --p.x; + c++; + //printf("pos=%ld x=%d y=%d\n", c - buf, p.x, p.y); + } + flip_point(cur, p); + } +} + +static int usage(char *prg) +{ + fprintf(stderr, "Usage: %s [-d debug_level] [-p part]\n", prg); + return 1; +} + +int main(ac, av) + int ac; + char **av; +{ + int opt, part = 1; + ulong res = 0; + + while ((opt = getopt(ac, av, "d:p:")) != -1) { + switch (opt) { + case 'd': + debug_level_set(atoi(optarg)); + break; + case 'p': /* 1 or 2 */ + part = atoi(optarg); + if (part < 1 || part > 2) + default: + return usage(*av); } } + pt_pool = pool_create("pool_points", 256, sizeof(point_t)); + + parse(); + printf("count=%d\n", count_points(cur)); printf("%s : res=%lu\n", *av, res); exit (0); } diff --git a/README.md b/README.md index 489f792..a31652e 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ - `C`: Days 1-9 #### Advent of Code 2020 - - `C`: Days 1-18 + - `C`: Days 1-18, 25 - `Bash`: Days 1-25 - `Cobol`: Day 1 (!!)