X-Git-Url: https://git.martlubbers.net/?a=blobdiff_plain;f=15b.c;h=029d305d71f97ead949a28a61e3e45495f0c3a88;hb=09f77b0ecadc0625753adfeb990142cf0c0f6735;hp=65d808181717bacad447388f38b53a1076609a67;hpb=354fc4258110cbc1e515b61a277896d06b8f7f21;p=advent21.git diff --git a/15b.c b/15b.c index 65d8081..029d305 100644 --- a/15b.c +++ b/15b.c @@ -1,14 +1,13 @@ #include -#include -#include #include -#include -#include +#include -#define min(a, b) ((a) < (b) ? (a) : (b)) -#define MFAC 1 +#define MFAC 5 struct point { int x; int y; }; +#define pnt(px, py) ((struct point){.x=(px), .y=(py)}) +struct q { struct point key; UT_hash_handle hh; }; +int dist[100*MFAC][100*MFAC]; int grid[100][100] = {0}; int maxx = 0; @@ -16,29 +15,17 @@ int maxy = 0; int get_grid(int x, int y) { - if (x == 0 && y == 0) - return 0; int r = grid[y%maxy][x%maxx] + y/maxy + x/maxx; - while (r > 9) - r -= 9; + if (r > 9) + return r % 9; return r; } -int dist[100*MFAC][100*MFAC]; - -int mindist(const void *l, const void *r) -{ - struct point lp = *(const struct point *)l; - struct point rp = *(const struct point *)r; - return dist[rp.y][rp.x]-dist[lp.y][lp.x]; -} - -struct point *is_in_q(struct point *q, size_t nq, int x, int y) +int qcmp(const void *l, const void *r) { - for (size_t i = 0; ikey.y][lp->key.x]-dist[rp->key.y][rp->key.x]; } int main() @@ -54,52 +41,43 @@ int main() } } - struct point q[100*MFAC*100*MFAC]; - size_t qp = 0; - struct point prev[100*MFAC][100*MFAC]; + struct q *q = NULL; -// grid[0][0] = 0; for (int y = 0; ykey = pnt(x, y); + HASH_ADD(hh, q, key, sizeof(struct point), i); } } dist[0][0] = 0; + HASH_SRT(hh, q, qcmp); - while (qp > 0) { -// printf("size of q: %lu\n", qp); - qsort(q, qp, sizeof(struct point), mindist); - qp--; - struct point u = q[qp]; + while (q != NULL) { + struct point u = q->key; + HASH_DELETE(hh, q, q); for (int dy = -1; dy <= 1; dy++) { for (int dx = -1; dx <= 1; dx++) { //Skip diagonal neigbours - if (dx == dy) + if (abs(dx) == abs(dy)) continue; //check if v is in Q - struct point *v = is_in_q(&q[0], qp, u.x+dx, u.y+dy); + struct q *v; + HASH_FIND(hh, q, &pnt(u.x+dx, u.y+dy), sizeof(struct point), v); if (v == NULL) continue; //Update dist if necessary - int alt = dist[u.y][u.x] + get_grid(v->x, v->y); - if (alt < dist[v->y][v->x]) { - dist[v->y][v->x] = alt; - prev[v->y][v->x] = u; + int alt = dist[u.y][u.x] + get_grid(v->key.x, v->key.y); + if (alt < dist[v->key.y][v->key.x]) { + dist[v->key.y][v->key.x] = alt; + //Reinsert with in correct position + HASH_DELETE(hh, q, v); + HASH_ADD_INORDER(hh, q, key, sizeof(struct point), v, qcmp); } } } } - printf("path: "); - struct point u = {.y=maxy*MFAC-1, .x=maxx*MFAC-1}; - do { - u = prev[u.y][u.x]; - printf("%d,%d ", u.x, u.y); - } while (u.x!= 0 && u.y != 0); - - printf("\n"); - printf("%d\n", dist[maxy*MFAC-1][maxx*MFAC-1]); }