commit c94c8b40f40a34d25d745fbd07f9e0b456364238
parent ec8e5a7343354704d5cab7d141db3cebd548c41a
Author: Louis Burda <quent.burda@gmail.com>
Date: Mon, 20 Mar 2023 13:54:06 +0100
Fixup day 11
Diffstat:
A | 11/info.mk | | | 4 | ++++ |
M | 11/main.c | | | 109 | ++++++++++++++++++++++++++++++++++++++++++++++--------------------------------- |
2 files changed, 67 insertions(+), 46 deletions(-)
diff --git a/11/info.mk b/11/info.mk
@@ -0,0 +1,4 @@
+11_SRC = 11/main.c common/main.c common/iccmp.c common/aoc.c common/util.c
+11_SRC += lib/libdvec/build/libdvec.a lib/liballoc/build/liballoc.a
+11_SRC += lib/libmaxint/build/libmaxint.a lib/libhashmap/build/libhashmap.a
+11_HDR = common/aoc.h common/iccmp.h common/util.h
diff --git a/11/main.c b/11/main.c
@@ -1,9 +1,12 @@
+#include "allocator.h"
#include "aoc.h"
#include "iccmp.h"
#include "hashmap.h"
+#include "util.h"
-#include <stdlib.h>
+#include <assert.h>
#include <stdio.h>
+#include <stdlib.h>
struct vec2 {
int x, y;
@@ -36,14 +39,14 @@ const char *solmap = "\
";
uint32_t
-pos_hasher(void *p, int len)
+pos_hasher(const void *p, size_t len)
{
- struct vec2 *d;
+ const struct vec2 *vec;
int hash;
- d = p;
- hash = (uint16_t) d->x;
- hash |= ((uint16_t) d->y) << 16;
+ vec = p;
+ hash = (uint16_t) vec->x;
+ hash |= ((uint16_t) vec->y) << 16;
return hash;
}
@@ -60,9 +63,8 @@ gen_map(struct hashmap *panels, struct vec2 *pos, int rot)
min.x = min.y = -2;
max.x = max.y = 2;
- iter = hashmap_iter();
- while (hashmap_next(panels, &iter)) {
- ppos = iter.link->key.key;
+ for (HASHMAP_ITER(panels, &iter)) {
+ ppos = iter.link->key;
min.x = MIN(min.x, ppos->x);
min.y = MIN(min.y, ppos->y);
max.x = MAX(max.x, ppos->x);
@@ -78,12 +80,12 @@ gen_map(struct hashmap *panels, struct vec2 *pos, int rot)
dims.x = max.x - min.x + 1;
dims.y = max.y - min.y + 1;
- map = CHKP(malloc((dims.x + 1) * dims.y));
+ map = malloc((dims.x + 1) * dims.y);
+ assert(map != NULL);
memset(map, '.', (dims.x + 1) * dims.y);
- iter = hashmap_iter();
- while (hashmap_next(panels, &iter)) {
- ppos = iter.link->key.key;
+ for (HASHMAP_ITER(panels, &iter)) {
+ ppos = iter.link->key;
color = *(int*)iter.link->value;
map[(ppos->y - min.y) * (dims.x + 1) + (ppos->x - min.x)] = color ? '#' : '.';
}
@@ -102,68 +104,78 @@ gen_map(struct hashmap *panels, struct vec2 *pos, int rot)
void
panels_init(struct hashmap *panels, int start_color)
{
- struct hashmap_link *read_color;
- struct hashmap_key key;
+ struct hashmap_link **link;
int color, rot, brot;
struct vec2 pos;
struct icc icc;
+ void *key, *value;
char *map;
+ int rc;
enum {
STATE_COLOR,
- STATE_ROT
+ STATE_ROTATE
} state;
- ASSERT(icc_init(&icc) == OK);
- ASSERT(icc_parse_inst(&icc, aoc.input, aoc.input_size) == OK);
-
- icc_set_debug(&icc, aoc.debug & 0b10);
+ icc_init(&icc);
+ icc_parse_inst(&icc, aoc.input, aoc.input_size);
pos.x = pos.y = 0;
- hashmap_set(panels, HASHMAP_KEY(&pos, sizeof(pos)), &start_color);
+ key = memdup(&pos, sizeof(pos));
+ hashmap_add(panels, key, sizeof(pos),
+ start_color == white ? &white : &black);
rot = 0;
color = 0;
state = STATE_COLOR;
- while (icc.status != ICC_HALT) {
+ while (icc.state != ICC_HALT) {
icc_step_inst(&icc);
- switch (icc.status) {
+ switch (icc.state) {
case ICC_OUTPUT:
if (state == STATE_COLOR) {
color = mi_cast_ul(&icc.out);
- ASSERT(color == 0 || color == 1);
- debug("OUTPUT %i %i: %i\n", pos.x, pos.y, color);
- key = HASHMAP_KEY(&pos, sizeof(pos));
- hashmap_set(panels, key, color ? &white : &black);
- state = STATE_ROT;
- } else if (state == STATE_ROT) {
+ 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;
+ } else {
+ key = memdup(&pos, sizeof(pos));
+ rc = hashmap_link_alloc(panels, link,
+ key, sizeof(pos), value);
+ assert(!rc);
+ }
+ state = STATE_ROTATE;
+ } else if (state == STATE_ROTATE) {
brot = mi_cast_ul(&icc.out);
- ASSERT(brot == 0 || brot == 1);
- debug("ROT %i %i: %i\n", pos.x, pos.y, brot);
+ assert(brot == 0 || brot == 1);
+ aoc_debug("ROT %i %i: %i\n", pos.x, pos.y, brot);
rot = (rot + (brot ? 1 : -1) + 4) % 4;
pos.x += dirs[rot].x;
pos.y += dirs[rot].y;
if (aoc.debug) {
map = gen_map(panels, &pos, rot);
- debug("%s", map);
+ aoc_debug("%s", map);
free(map);
}
state = STATE_COLOR;
}
break;
case ICC_INPUT:
- key = HASHMAP_KEY(&pos, sizeof(pos));
- if (hashmap_get(panels, key, &read_color)) {
- debug("INPUT %i %i: %i\n", pos.x, pos.y, *((int*)read_color->value));
- mi_setv(&icc.in, *((int*)read_color->value), MI_POS);
+ 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, *((int*)(*link)->value), MI_POS);
} else {
- debug("INPUT %i %i: 0\n", pos.x, pos.y);
+ aoc_debug("INPUT %i %i: 0\n", pos.x, pos.y);
mi_setv(&icc.in, 0, MI_POS);
}
break;
}
}
- icc_free(&icc);
+ icc_deinit(&icc);
}
void
@@ -173,17 +185,19 @@ part1(void)
struct hashmap_iter iter;
int count;
- hashmap_init(&panels, 100, pos_hasher);
+ hashmap_init(&panels, 100, pos_hasher,
+ hashmap_default_keycmp, &stdlib_strict_heap_allocator);
panels_init(&panels, black);
count = 0;
- iter = hashmap_iter();
- while (hashmap_next(&panels, &iter))
+ for (HASHMAP_ITER(&panels, &iter))
count += 1;
- aoc.answer = CHKP(aprintf("%i", count));
+ aoc.answer = aprintf("%i", count);
aoc.solution = "2088";
- hashmap_free(&panels);
+ for (HASHMAP_ITER(&panels, &iter))
+ free(iter.link->key);
+ hashmap_deinit(&panels);
}
void
@@ -193,12 +207,15 @@ part2(void)
struct hashmap_iter iter;
char *map;
- hashmap_init(&panels, 100, pos_hasher);
+ hashmap_init(&panels, 100, pos_hasher,
+ hashmap_default_keycmp, &stdlib_strict_heap_allocator);
panels_init(&panels, white);
map = gen_map(&panels, NULL, 0);
- aoc.answer = CHKP(map);
+ aoc.answer = map;
aoc.solution = solmap;
- hashmap_free(&panels);
+ for (HASHMAP_ITER(&panels, &iter))
+ free(iter.link->key);
+ hashmap_deinit(&panels);
}