commit ce61311b9842de5c9be9c73b75a01455e9c18073
parent 4bf1114b3007996077a0647175c00f0882a0261c
Author: Louis Burda <quent.burda@gmail.com>
Date: Mon, 20 Mar 2023 16:47:08 +0100
Finish day 13
Diffstat:
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);