#include "allocator.h" #include "aoc.h" #include "vec_s.h" #include "dvec_s.h" #include "util.h" #include #include #include static char * load_map(size_t *maxx, size_t *h) { const char *lpos, *lend; size_t rows, cols, len; char line[256]; char *map; map = NULL; rows = 0; cols = 0; lpos = aoc.input; lend = lpos + aoc.input_size; while (readtok(line, sizeof(line), '\n', &lpos, lend)) { len = strlen(line); if (!len) continue; if (!cols) cols = len; assert(len == cols); map = realloc(map, cols * (rows + 1) + 1); memcpy(map + cols * rows, line, cols); rows += 1; } map[rows * cols] = '\0'; *maxx = cols; *h = rows; return map; } static void print_map(char *map, size_t w, size_t h) { size_t y; for (y = 0; y < h; y++) aoc_debug("%.*s\n", w, &map[y * w]); } static uint64_t map_id(char *map, size_t w, size_t h) { size_t x, y, b; uint64_t id; b = 0; id = 0; for (y = 0; y < h; y++) { for (x = 0; x < w; x++) { if (map[y * w + x] == '#') id |= 1 << b; b += 1; } } return id; } static void step(char *prev, char *next, size_t w, size_t h) { struct vec2i pos, npos; size_t i, k, count; for (pos.y = 0; (size_t) pos.y < h; pos.y++) { for (pos.x = 0; (size_t) pos.x < w; pos.x++) { count = 0; for (i = 0; i < 4; i++) { vec2i_add(&npos, &pos, &adj[i]); if (npos.x < 0 || (size_t) npos.x >= w) continue; if (npos.y < 0 || (size_t) npos.y >= h) continue; k = (size_t) npos.y * w + (size_t) npos.x; if (prev[k] == '#') count += 1; } k = (size_t) pos.y * w + (size_t) pos.x; if (prev[k] == '#' && count != 1) { next[k] = '.'; } else if (prev[k] == '.' && (count == 1 || count == 2)) { next[k] = '#'; } else { next[k] = prev[k]; } } } } void part1(void) { struct dvec ids; char *map, *next, *tmp; uint64_t *slot, id; size_t w, h, i; uint64_t answer; map = load_map(&w, &h); next = memdup(map, w * h + 1); dvec_init(&ids, sizeof(uint64_t), 0, &stdlib_strict_heap_allocator); slot = dvec_add_slot(&ids); *slot = map_id(map, w, h); aoc_debug("INIT\n"); print_map(map, w, h); answer = 0; while (!answer) { step(map, next, w, h); tmp = map; map = next; next = tmp; aoc_debug("$ %i\n", ids.len); print_map(map, w, h); id = map_id(map, w, h); for (i = 0; i < ids.len; i++) { aoc_debug("%lu vs %lu\n", id, *(uint64_t *)dvec_at(&ids, i)); if (*(uint64_t *)dvec_at(&ids, i) == id) { answer = id; break; } } slot = dvec_add_slot(&ids); *slot = id; } aoc.answer = aprintf("%lu", answer); aoc.solution = "30446641"; dvec_deinit(&ids); free(next); free(map); }