#include <stdbool.h> #include <stdio.h> #include <stdlib.h> #include "aocutils.h" bool TGvalid(struct TextGrid *tg, unsigned row, unsigned col) { if (row >= tg->rows) return false; if (col >= tg->cols) return false; return true; } char *TGcharptr(struct TextGrid *tg, unsigned row, unsigned col) { if (!TGvalid(tg, row, col)) return NULL; return tg->data + (row * tg->cols) + col; } unsigned TGcol(struct TextGrid *tg, char *p) { return (p - tg->data) % tg->cols; } unsigned TGrow(struct TextGrid *tg, char *p) { return (p - tg->data) / tg->cols; } // TODO: rewrite this shit size_t linearize2d(unsigned width, unsigned row, unsigned col) { return (row * width) + col; } size_t text2array(unsigned **dst, const char *r) { unsigned *a = malloc(512 * sizeof *a); size_t na = 0, sa = 512; char *err; unsigned v; for (;;) { if (na == sa) { // grow the array (by golden ratio) unsigned *tmp = realloc(a, ((13*sa) / 8) * sizeof *tmp); if (!tmp) exit(EXIT_FAILURE); a = tmp; sa = (13*sa) / 8; } v = strtoul(r, &err, 10); a[na++] = v; if (!*err) break; r = err; } *dst = a; return na; } size_t slurp(char **dst, const char *fn) { if (*dst) { fprintf(stderr, "slurp() must be called with a pointer to void!\n"); exit(EXIT_FAILURE); } FILE *h = fopen(fn, "r"); if (!h) { perror(fn); exit(EXIT_FAILURE); } int ch; char *tmp = malloc(512); size_t s = 512; size_t r = 0; while ((ch = fgetc(h)) != EOF) { if (r+1 == s) { // grow the array (by golden ratio) char *ttmp = realloc(tmp, (13*s) / 8); if (ttmp) { tmp = ttmp; s = (13*s) / 8; } else { free(tmp); return 0; } } tmp[r++] = ch; } fclose(h); tmp[r] = 0; *dst = tmp; return r; } unsigned distance(unsigned a, unsigned b) { if (a > b) return a - b; return b - a; } unsigned max3u(unsigned a, unsigned b, unsigned c) { if (a > b) { if (a > c) return a; return c; } else { if (b > c) return b; } return c; } unsigned min3u(unsigned a, unsigned b, unsigned c) { if (a < b) { if (a < c) return a; return c; } else { if (b < c) return b; } return c; }