Index: aoc2025.c ================================================================== --- aoc2025.c +++ aoc2025.c @@ -4,10 +4,76 @@ #include #include #include #include "aocdailies.h" #include "aocutils.h" + +#if 0 +/* === aocYYYYDD ======================================================= +===================================================================== */ +void aocYYYYDD(char *data, size_t len) { + (void)len; // unused argument +} +#endif + +/* === aoc202504 ======================================================= +===================================================================== */ +static unsigned evolve(struct RectangularMap *rm, unsigned src) { + unsigned changes = 0; + unsigned dst = 1 - src; + for (int row = 0; row < rm->rows; row++) { + for (int col = 0; col < rm->cols; col++) { + char cc = RMcharat(rm + src, col, row); + char *destin = RMcharptr(rm + dst, col, row); + if (cc == '@') { + unsigned nearby = 0; + for (int deltarow = -1; deltarow <= 1; deltarow++) { + for (int deltacol = -1; deltacol <= 1; deltacol++) { + nearby += (RMcharat(rm + src, col+deltacol, + row+deltarow) == '@'); + } + } + nearby -= 1; // remove self + if (nearby < 4) { + *destin = '.'; + changes++; + } else { + *destin = '@'; + } + } else if (cc != 0) { + *destin = '.'; + } else { + *destin = 0; // shouldn't happen + } + } + } + return changes; +} + +void aoc202504(char *data, size_t len) { + (void)len; // unused argument + struct RectangularMap rm[2] = {0}; + while (*data) { + char *data2 = data; + while (*data != '\n') data++; + *data = 0; // erase newline + RMaddline(rm + 0, data2); + RMaddline(rm + 1, data2); // set both rm's to the same thing + *data++ = '\n'; // unerase newline and skip it + } + unsigned part1 = evolve(rm, 0); // evolve from rm[0] to rm[1] + unsigned part2 = part1, src = 1; + for (;;) { + unsigned tmp = evolve(rm, src); // keep evolving + if (tmp == 0) break; // STOP + src = 1 - src; // back and forth + part2 += tmp; // add changes in this round + } + printf("P1: %u; P2: %u\n", part1, part2); + RMfree(rm); + RMfree(rm + 1); +} /* === aoc202503 ======================================================= ===================================================================== */ static long long unsigned maxj(const unsigned char *b, unsigned blen, unsigned nlen) { if (nlen == 0) return 0; Index: aocdailies.c ================================================================== --- aocdailies.c +++ aocdailies.c @@ -4,10 +4,11 @@ aocfunc *aocselect(unsigned y, unsigned d) { aocfunc *p; switch (y * 100 + d) { default: p = NULL; break; + case 202504: p = aoc202504; break; case 202503: p = aoc202503; break; case 202502: p = aoc202502; break; case 202501: p = aoc202501; break; // YYYYdd ==> aocYYYYdd Index: aocdailies.h ================================================================== --- aocdailies.h +++ aocdailies.h @@ -4,10 +4,11 @@ #include typedef void aocfunc(char *, size_t); aocfunc *aocselect(unsigned, unsigned); +aocfunc aoc202504; aocfunc aoc202503; aocfunc aoc202502; aocfunc aoc202501; aocfunc aoc202422; Index: aocutils.c ================================================================== --- aocutils.c +++ aocutils.c @@ -2,10 +2,62 @@ #include #include #include #include #include "aocutils.h" + +char RMcharat(struct RectangularMap *sm, int col, int row) { + if (col < 0) return 0; + if (row < 0) return 0; + if (col >= sm->cols) return 0; + if (row >= sm->rows) return 0; + return sm->data[row*sm->cols + col]; +} + +char *RMcharptr(struct RectangularMap *sm, int col, int row) { + if (col < 0) return NULL; + if (row < 0) return NULL; + if (col >= sm->cols) return NULL; + if (row >= sm->rows) return NULL; + return sm->data + row*sm->cols + col; +} + +void RMcopy(struct RectangularMap *restrict dst, + const struct RectangularMap *restrict src) { + size_t size = (size_t)src->cols * (size_t)src->rows; + char *tmp = realloc(dst->data, size); + if (tmp == NULL) { + fprintf(stderr, "not enough memory\n"); + exit(EXIT_FAILURE); + } + dst->data = tmp; + memcpy(dst->data, src->data, size); +} + +void RMaddline(struct RectangularMap *sm, const char *lin) { + int linlen = strlen(lin); + if (sm->cols && (sm->cols != linlen)) { + // error + fprintf(stderr, "wrong line length!\n"); + exit(EXIT_FAILURE); + } + if (sm->cols == 0) sm->cols = linlen; + char *tmp = realloc(sm->data, (size_t)(sm->rows+1) * (size_t)sm->cols); + if (tmp == NULL) { + fprintf(stderr, "not enough memory\n"); + exit(EXIT_FAILURE); + } + sm->data = tmp; + memcpy(sm->data + sm->rows*sm->cols, lin, (size_t)sm->cols); + sm->rows += 1; +} + +void RMfree(struct RectangularMap *sm) { + free(sm->data); + sm->data = NULL; + sm->cols = sm->rows = 0; +} static uint32_t f(uint32_t x, uint32_t y, uint32_t z) { return (x & y) | (~x & z); } Index: aocutils.h ================================================================== --- aocutils.h +++ aocutils.h @@ -6,10 +6,21 @@ struct TextGrid { unsigned cols, rows; char *data; // may have '\n' at end of rows }; +struct RectangularMap { + int cols, rows; + char *data; +}; +char RMcharat(struct RectangularMap *sm, int col, int row); +char *RMcharptr(struct RectangularMap *sm, int col, int row); +void RMcopy(struct RectangularMap *restrict dst, + const struct RectangularMap *restrict src); +void RMaddline(struct RectangularMap *sm, const char *lin); +void RMfree(struct RectangularMap *sm); + long long unsigned upow(unsigned base, unsigned exponent); void md5mini(unsigned char *dstarr, const char *src); bool TGvalid(struct TextGrid *tg, unsigned col, unsigned row);