aoc-2019-c

git clone https://git.sinitax.com/sinitax/aoc-2019-c
Log | Files | Refs | README | sfeed.txt

commit ce61311b9842de5c9be9c73b75a01455e9c18073
parent 4bf1114b3007996077a0647175c00f0882a0261c
Author: Louis Burda <quent.burda@gmail.com>
Date:   Mon, 20 Mar 2023 16:47:08 +0100

Finish day 13

Diffstat:
M06/main.c | 9+++++----
M10/main.c | 9+++++----
M11/main.c | 14+++++++-------
D13/Makefile | 15---------------
A13/info.mk | 4++++
M13/main.c | 123+++++++++++++++++++++++++++++++++++++++++++++++--------------------------------
Mcommon/icc.c | 14++++++++------
Mcommon/icc.h | 2++
Mcommon/iccmp.c | 32+++++++++++++++++---------------
Mcommon/iccmp.h | 2++
Mcommon/main.c | 6++----
11 files changed, 126 insertions(+), 104 deletions(-)

diff --git a/06/main.c b/06/main.c @@ -25,7 +25,7 @@ planets_get(const char *name) struct hashmap_link *link; link = hashmap_get(&planets, name, strlen(name)); - return link ? link->value : NULL; + return link ? link->value.p : NULL; } struct planet * @@ -42,7 +42,8 @@ planets_add(const char *name) dvec_init(&p->children, sizeof(struct planet *), 3, &stdlib_heap_allocator); - rc = hashmap_add(&planets, aprintf("%s", name), strlen(name), p); + rc = hashmap_add(&planets, aprintf("%s", name), strlen(name), + (struct hashmap_val) {.p = p}); assert(!rc); return p; @@ -89,7 +90,7 @@ planets_deinit() for (HASHMAP_ITER(&planets, &iter)) { free(iter.link->key); - p = iter.link->value; + p = iter.link->value.p; dvec_deinit(&p->children); free(p->name); free(p); @@ -109,7 +110,7 @@ part1(void) orbits = 0; for (HASHMAP_ITER(&planets, &iter)) { - p = iter.link->value; + p = iter.link->value.p; while (p->parent) { orbits += 1; p = p->parent; diff --git a/10/main.c b/10/main.c @@ -130,14 +130,15 @@ get_vis(struct hashmap *hm, struct asteroid *a1) link = hashmap_get(hm, &dir, sizeof(dir)); if (link) { - tmp = link->value; + tmp = link->value.p; odir = (struct dir) { tmp->x - a1->x, tmp->y - a1->y }; dir = (struct dir) { a2->x - a1->x, a2->y - a1->y }; if (ABS(odir.dx) + ABS(odir.dy) > ABS(dir.dx) + ABS(dir.dy)) - link->value = a2; + link->value.p = a2; } else { key = memdup(&dir, sizeof(struct dir)); - rc = hashmap_add(hm, key, sizeof(struct dir), a2); + rc = hashmap_add(hm, key, sizeof(struct dir), + (struct hashmap_val) {.p = a2}); assert(!rc); } } @@ -231,7 +232,7 @@ part2(void) assert(list != NULL); i = 0; for (HASHMAP_ITER(&dirmap, &iter)) - list[i++] = iter.link->value; + list[i++] = iter.link->value.p; for (i = 0; i < len; i++) { for (k = 0; k < len - 1; k++) { diff --git a/11/main.c b/11/main.c @@ -87,7 +87,7 @@ gen_map(struct hashmap *panels, struct vec2 *pos, int rot) for (HASHMAP_ITER(panels, &iter)) { ppos = iter.link->key; - color = *(int*)iter.link->value; + color = iter.link->value.i; map[(ppos->y - min.y) * (dims.x + 1) + (ppos->x - min.x)] = color ? '#' : '.'; } @@ -123,7 +123,7 @@ panels_init(struct hashmap *panels, int start_color) pos.x = pos.y = 0; key = memdup(&pos, sizeof(pos)); hashmap_add(panels, key, sizeof(pos), - start_color == white ? &white : &black); + (struct hashmap_val) {.i = start_color}); rot = 0; color = 0; @@ -136,14 +136,14 @@ panels_init(struct hashmap *panels, int start_color) color = (int) mi_cast_ul(&icc.out); assert(color == 0 || color == 1); aoc_debug("OUTPUT %i %i: %i\n", pos.x, pos.y, color); - value = color ? &white : &black; link = hashmap_link_pos(panels, &pos, sizeof(pos)); if (*link) { - (*link)->value = value; + (*link)->value.i = color; } else { key = memdup(&pos, sizeof(pos)); rc = hashmap_link_alloc(panels, link, - key, sizeof(pos), value); + key, sizeof(pos), + (struct hashmap_val) {.i = color}); assert(!rc); } state = STATE_ROTATE; @@ -166,8 +166,8 @@ panels_init(struct hashmap *panels, int start_color) link = hashmap_link_get(panels, &pos, sizeof(pos)); if (link) { aoc_debug("INPUT %i %i: %i\n", pos.x, pos.y, - *((int*)(*link)->value)); - mi_setv(&icc.in, (mi_ul) *((int*)(*link)->value), + (*link)->value.i); + mi_setv(&icc.in, (mi_ul) (*link)->value.i, MI_POS); } else { aoc_debug("INPUT %i %i: 0\n", pos.x, pos.y); diff --git a/13/Makefile b/13/Makefile @@ -1,15 +0,0 @@ -CFLAGS = -g -I ../../libs/include -L ../../libs/build -LDLIBS = -liccmp -laoc - -all: lib main - -clean: - rm -f main - -lib: - make -C ../../libs - -main: main.c ../../libs/build/* - $(CC) -o $@ $< $(CFLAGS) $(LDLIBS) - -.PHONY: all clean lib diff --git a/13/info.mk b/13/info.mk @@ -0,0 +1,4 @@ +13_SRC = 13/main.c common/main.c common/iccmp.c common/aoc.c common/util.c +13_SRC += lib/libdvec/build/libdvec.a lib/liballoc/build/liballoc.a +13_SRC += lib/libmaxint/build/libmaxint.a lib/libhashmap/build/libhashmap.a +13_HDR = common/aoc.h common/iccmp.h common/util.h diff --git a/13/main.c b/13/main.c @@ -1,9 +1,12 @@ +#include "allocator.h" #include "aoc.h" #include "iccmp.h" #include "hashmap.h" #include "maxint.h" #include "util.h" +#include <assert.h> +#include <stddef.h> #include <stdint.h> #include <stdlib.h> #include <stdio.h> @@ -23,14 +26,14 @@ enum { }; uint32_t -pos_hasher(void *key, int len) +pos_hasher(const void *key, size_t len) { - struct vec2 *pos; + const struct vec2 *pos; uint32_t hash; pos = key; - hash = (pos->x & 0xffffffff); - hash = (hash << 4) | (pos->y & 0xffffffff); + hash = ((uint32_t) pos->x & 0xffffffff); + hash = (hash << 4) | ((uint32_t) pos->y & 0xffffffff); return hash; } @@ -45,9 +48,8 @@ print_map(struct hashmap *map) int x, y; size.x = size.y = 1; - iter = hashmap_iter(); - while (hashmap_next(map, &iter)) { - ppos = iter.link->key.key; + for (HASHMAP_ITER(map, &iter)) { + ppos = iter.link->key; size.x = MAX(size.x, ppos->x + 1); size.y = MAX(size.y, ppos->y + 1); } @@ -56,90 +58,104 @@ print_map(struct hashmap *map) for (x = 0; x < size.x; x++) { pos.x = x; pos.y = y; - if (hashmap_get(map, HASHMAP_KEY(&pos, sizeof(pos)), &link)) + link = hashmap_get(map, &pos, sizeof(pos)); + if (link) tile = tiles[link->value.i]; else tile = tiles[EMPTY]; - debug("%c", tile); + aoc_debug("%c", tile); } - debug("\n"); + aoc_debug("\n"); } - debug("\n"); + aoc_debug("\n"); } void part1(void) { + struct hashmap_link **link; struct hashmap_iter iter; struct hashmap map; struct icc icc; struct vec2 pos; int outind, outvec[3]; - int count; + int rc, count; + void *key; - icc_init(&icc); - hashmap_init(&map, 100, pos_hasher); + hashmap_init(&map, 100, pos_hasher, hashmap_default_keycmp, + &stdlib_strict_heap_allocator); - ASSERT(icc_parse_inst(&icc, aoc.input, aoc.input_size) == ICC_OK); + icc_init(&icc); + icc_parse_inst(&icc, aoc.input, aoc.input_size); outind = 0; - while (icc.status != ICC_HALT) { + while (icc.state != ICC_HALT) { icc_step_inst(&icc); - switch (icc.status) { + switch (icc.state) { case ICC_OUTPUT: - outvec[outind] = mi_cast_ul(&icc.out); + outvec[outind] = (int) mi_cast_ul(&icc.out); outind = (outind + 1) % 3; if (!outind) { pos.x = outvec[0]; pos.y = outvec[1]; - hashmap_set(&map, HASHMAP_KEY(&pos, sizeof(pos)), - HASHMAP_VAL(.i = outvec[2])); + link = hashmap_link_pos(&map, &pos, sizeof(pos)); + if (*link) { + (*link)->value.i = outvec[2]; + } else { + key = memdup(&pos, sizeof(pos)); + rc = hashmap_link_alloc(&map, link, key, sizeof(pos), + (struct hashmap_val) {.i = outvec[2]}); + assert(!rc); + } } break; } } count = 0; - iter = hashmap_iter(); - while (hashmap_next(&map, &iter)) { + for (HASHMAP_ITER(&map, &iter)) { if (iter.link->value.i == BLOCK) count += 1; } - aoc.answer = CHKP(aprintf("%i", count)); + aoc.answer = aprintf("%i", count); + aoc.solution = "329"; - hashmap_free(&map); - icc_free(&icc); + for (HASHMAP_ITER(&map, &iter)) + free(iter.link->key); + hashmap_deinit(&map); + icc_deinit(&icc); } void part2(void) { + struct hashmap_link **link; struct hashmap_iter iter; struct hashmap map; - struct maxint init; + struct maxint addr = MI_INIT; + struct maxint val = MI_INIT; + mi_ul addr_ul, val_ul; struct icc icc; struct vec2 pos, ball, paddle; int outind, outvec[3]; - int score, dir; - - icc_init(&icc); - hashmap_init(&map, 100, pos_hasher); - icc_set_debug(&icc, aoc.debug == 2); + int rc, score, dir; + void *key; - ASSERT(icc_parse_inst(&icc, aoc.input, aoc.input_size) == ICC_OK); + hashmap_init(&map, 100, pos_hasher, hashmap_default_keycmp, + &stdlib_strict_heap_allocator); - init = MI_INIT; - mi_setv(&init, 2, MI_POS); - icc_set_val(&icc, 0, &init); - mi_free(&init); + icc_init(&icc); + icc_parse_inst(&icc, aoc.input, aoc.input_size); + icc_write(&icc, mi_imm(&addr, &addr_ul, 0, MI_POS), + mi_imm(&val, &val_ul, 2, MI_POS)); score = 0; outind = 0; - while (icc.status != ICC_HALT) { + while (icc.state != ICC_HALT) { icc_step_inst(&icc); - switch (icc.status) { + switch (icc.state) { case ICC_INPUT: if (paddle.x < ball.x) { mi_setv(&icc.in, 1, MI_POS); @@ -152,23 +168,30 @@ part2(void) dir = 0; } if (aoc.debug) { - debug("Score: %i, Ball: %i %i, Paddle: %i %i, Dir: %i\n", + aoc_debug("Score: %i, Ball: %i %i, Paddle: %i %i, Dir: %i\n", score, ball.x, ball.y, paddle.x, paddle.y, dir); print_map(&map); } break; case ICC_OUTPUT: - outvec[outind] = mi_cast_ul(&icc.out); + outvec[outind] = (int) mi_cast_ul(&icc.out) + * (icc.out.sign == MI_POS ? 1 : -1); outind = (outind + 1) % 3; if (!outind) { + pos.x = outvec[0]; + pos.y = outvec[1]; if (pos.x == -1 && pos.y == 0) { score = outvec[2]; } else { - pos.x = outvec[0]; - pos.y = outvec[1]; - //debug("> %i %i\n", pos.x, pos.y); - hashmap_set(&map, HASHMAP_KEY(&pos, sizeof(pos)), - HASHMAP_VAL(.i = outvec[2])); + link = hashmap_link_pos(&map, &pos, sizeof(pos)); + if (*link) { + (*link)->value.i = outvec[2]; + } else { + key = memdup(&pos, sizeof(pos)); + rc = hashmap_link_alloc(&map, link, key, sizeof(pos), + (struct hashmap_val) {.i = outvec[2]}); + assert(!rc); + } if (outvec[2] == BALL) { ball.x = pos.x; ball.y = pos.y; @@ -182,9 +205,11 @@ part2(void) } } - aoc.answer = CHKP(aprintf("%i", score)); - - hashmap_free(&map); - icc_free(&icc); + aoc.answer = aprintf("%i", score); + aoc.solution = "15973"; + for (HASHMAP_ITER(&map, &iter)) + free(iter.link->key); + hashmap_deinit(&map); + icc_deinit(&icc); } diff --git a/common/icc.c b/common/icc.c @@ -30,6 +30,8 @@ icc_init(struct icc *icc) icc->write_addr = 0; icc->abort_on_err = true; + icc->debug = getenv("ICC_DEBUG") != NULL; + icc->line_terminated = true; rc = dvec_init(&icc->instructions, @@ -103,7 +105,7 @@ icc_debug_op_pre(struct icc *icc) { int inst, rc; - if (!aoc.debug) return; + if (!icc->debug) return; rc = icc_get_inst(icc, icc->rip, &inst); if (!rc) fprintf(stderr, "%04i: (%05i) ", icc->rip, inst); @@ -117,7 +119,7 @@ icc_debug_op_main(struct icc *icc, const char *opstr, size_t n) { int i, rc, val, val2, inst; - if (!aoc.debug) return; + if (!icc->debug) return; rc = icc_get_inst(icc, icc->rip, &inst); assert(!rc); @@ -150,7 +152,7 @@ icc_debug_op_post(struct icc *icc, int dst) int val, inst; int rc; - if (!aoc.debug) return; + if (!icc->debug) return; rc = icc_get_inst(icc, icc->rip, &inst); assert(!rc); @@ -168,7 +170,7 @@ icc_debug_op_post(struct icc *icc, int dst) void icc_debug_op(struct icc *icc, const char *opstr, size_t n) { - if (!aoc.debug) return; + if (!icc->debug) return; icc_debug_op_main(icc, opstr, n); fprintf(stderr, "\n"); @@ -439,7 +441,7 @@ icc_step_inst(struct icc *icc) break; } - if (aoc.debug) { + if (icc->debug) { if (!icc->line_terminated) { fprintf(stderr, "\n"); icc->line_terminated = true; @@ -534,7 +536,7 @@ icc_debug_dump(struct icc *icc, struct dvec *inst) int *rip; size_t i; - if (!aoc.debug) return; + if (!icc->debug) return; rip = icc->instructions.data; for (i = 0; i < icc->instructions.len; i++, rip++) { diff --git a/common/icc.h b/common/icc.h @@ -44,6 +44,8 @@ struct icc { int write_addr; bool abort_on_err; + bool debug; + bool line_terminated; int rip, base; diff --git a/common/iccmp.c b/common/iccmp.c @@ -47,6 +47,8 @@ icc_init(struct icc *icc) icc->state = ICC_RUN; + icc->debug = getenv("ICC_DEBUG") != NULL; + mi_init(&icc->rip); mi_setv(&icc->rip, 0, MI_POS); @@ -68,7 +70,7 @@ icc_init(struct icc *icc) icc->line_terminated = true; - rc = hashmap_init(&icc->instructions, 256, icc_addr_hasher, + rc = hashmap_init(&icc->instructions, 1024, icc_addr_hasher, icc_hashmap_cmp, &stdlib_strict_heap_allocator); assert(!rc); } @@ -93,8 +95,8 @@ icc_deinit(struct icc *icc) for (HASHMAP_ITER(&icc->instructions, &iter)) { mi_deinit(iter.link->key); free(iter.link->key); - mi_deinit(iter.link->value); - free(iter.link->value); + mi_deinit(iter.link->value.p); + free(iter.link->value.p); } hashmap_deinit(&icc->instructions); @@ -153,7 +155,7 @@ icc_parse_inst(struct icc *icc, const char *str, size_t len) mi_setv(val, (mi_ul) ABS(v), v >= 0 ? MI_POS : MI_NEG); rc = hashmap_add(&icc->instructions, key, - sizeof(struct maxint), val); + sizeof(struct maxint), (struct hashmap_val) {.p = val}); assert(!rc); rip += 1; @@ -190,7 +192,7 @@ icc_value_str(struct icc *icc, struct maxint *addr, size_t zfill) static void icc_debug_op_pre(struct icc *icc) { - if (!aoc.debug) return; + if (!icc->debug) return; fprintf(stderr, "%*s: ", 5, icc_literal_str(icc, &icc->rip, 0)); fprintf(stderr, "(%*s) ", 5, icc_value_str(icc, &icc->rip, 5)); @@ -203,7 +205,7 @@ icc_debug_op_main(struct icc *icc, struct maxint *tmp, const char *opstr, int n) struct maxint *inst, *val; int i, rc, instint; - if (!aoc.debug) return; + if (!icc->debug) return; rc = icc_read(icc, &icc->rip, &inst); assert(!rc); @@ -245,7 +247,7 @@ icc_debug_op_main(struct icc *icc, struct maxint *tmp, const char *opstr, int n) static void icc_debug_op_post(struct icc *icc, struct maxint *addr) { - if (!aoc.debug) return; + if (!icc->debug) return; fprintf(stderr, " -> [%s]=%s\n", icc_literal_str(icc, addr, 0), icc_value_str(icc, addr, 0)); @@ -255,7 +257,7 @@ icc_debug_op_post(struct icc *icc, struct maxint *addr) static void icc_debug_op(struct icc *icc, struct maxint *tmp, const char *opstr, int n) { - if (!aoc.debug) return; + if (!icc->debug) return; icc_debug_op_main(icc, tmp, opstr, n); fprintf(stderr, "\n"); @@ -476,7 +478,7 @@ icc_inst_base(struct icc *icc) mi_add(&icc->rip, &icc->rip, mi_tmp(2)); icc->state = ICC_RUN; - if (aoc.debug) { + if (icc->debug) { fprintf(stderr, " -> BASE:%s\n", icc_literal_str(icc, &icc->base, 0)); icc->line_terminated = true; @@ -542,7 +544,7 @@ icc_step_inst(struct icc *icc) break; } - if (aoc.debug) { + if (icc->debug) { if (!icc->line_terminated) { fprintf(stderr, "\n"); icc->line_terminated = true; @@ -573,8 +575,8 @@ icc_write_any(struct icc *icc, struct maxint *addr, struct maxint *value) link = hashmap_link_pos(&icc->instructions, key, sizeof(struct maxint)); if (!*link) { - rc = hashmap_link_alloc(&icc->instructions, link, - key, sizeof(struct maxint), val); + rc = hashmap_link_alloc(&icc->instructions, link, key, + sizeof(struct maxint), (struct hashmap_val) {.p = val}); assert(!rc); } @@ -596,7 +598,7 @@ icc_write(struct icc *icc, struct maxint *addr, struct maxint *val) icc_write_any(icc, addr, val); } else { - mi_set(link->value, val); + mi_set(link->value.p, val); } return 0; @@ -617,7 +619,7 @@ icc_read(struct icc *icc, struct maxint *addr, struct maxint **out) link = icc_write_any(icc, addr, mi_tmp(0)); } - *out = link->value; + *out = link->value.p; return 0; } @@ -702,7 +704,7 @@ icc_get_dest(struct icc *icc, struct maxint *tmp, int param, struct maxint *out) void icc_debug_print(struct icc *icc, struct maxint *addr) { - if (!aoc.debug) return; + if (!icc->debug) return; fprintf(stderr, "[%s] = %s\n", icc_literal_str(icc, addr, 0), icc_value_str(icc, addr, 0)); diff --git a/common/iccmp.h b/common/iccmp.h @@ -46,6 +46,8 @@ struct icc { struct maxint write_addr; bool abort_on_err; + bool debug; + /* general purpose registers */ struct maxint r1, r2, r3, r4, tmp; diff --git a/common/main.c b/common/main.c @@ -8,7 +8,6 @@ struct aoc aoc; int main(int argc, const char **argv) { - const char *envvar; FILE *f; if (argc <= 1) { @@ -19,11 +18,10 @@ main(int argc, const char **argv) aoc.part = atoi(argv[1]); aoc.args = &argv[2]; - envvar = getenv("AOCDEBUG"); - aoc.debug = envvar ? atoi(envvar) : 0; + aoc.debug = getenv("AOC_DEBUG") != NULL; /* parse user input */ - aoc.inputfile = getenv("AOCINPUT"); + aoc.inputfile = getenv("AOC_INPUT"); if (!aoc.inputfile) aoc.inputfile = "input"; else aoc_debug("Using input file: '%s'\n", aoc.inputfile);