common.c (3362B)
1 #include "common.h" 2 3 void printgd(gd *g) { 4 size_t i, j; 5 for (j = 0; j < g->maxy; j++) { 6 for (i = 494; i < 504; i++) { 7 uint8_t v = g->grid[i * g->h + j]; 8 if (v == 0) 9 printf("."); 10 else if (v == 1) 11 printf("#"); 12 else 13 printf("o"); 14 } 15 printf("\n"); 16 } 17 } 18 19 int sandfall(gd *g) { 20 size_t x = 500, y = 0; 21 22 while (y < g->maxy) { 23 assert(x > 0); 24 if (g->grid[x * g->h + (y + 1)] == 0) { 25 y++; 26 } else if (g->grid[(x - 1) * g->h + (y + 1)] == 0) { 27 x--; 28 y++; 29 } else if (g->grid[(x + 1) * g->h + (y + 1)] == 0) { 30 x++; 31 y++; 32 } else { 33 g->grid[x * g->h + y] = 2; 34 if (x == 500 && y == 0) 35 return 3; 36 return 0; 37 } 38 } 39 return 1; 40 } 41 42 gd *parse(char **lines, size_t nlines, int floor) { 43 stack_u64 xs[nlines + 1], ys[nlines + 1]; 44 char *p; 45 size_t i, j; 46 47 uint64_t minx = UINT64_MAX, maxx = 0, miny = UINT64_MAX, maxy = 0; 48 49 for (i = 0; i < nlines; i++) { 50 stack_u64_init(&xs[i]); 51 stack_u64_init(&ys[i]); 52 uint64_t t; 53 size_t c = 0; 54 p = lines[i]; 55 while ((p = sread_next_u64(&t, p)) != NULL) { 56 if (c % 2 == 0) { 57 stack_u64_push(&xs[i], t); 58 if (t < minx) 59 minx = t; 60 if (t > maxx) 61 maxx = t; 62 } else { 63 stack_u64_push(&ys[i], t); 64 if (t < miny) 65 miny = t; 66 if (t > maxy) 67 maxy = t; 68 } 69 c++; 70 } 71 } 72 73 if (floor) { 74 maxy += 2; 75 maxx += maxy + 1; // at most diagonal 76 stack_u64_init(&xs[nlines]); 77 stack_u64_init(&ys[nlines]); 78 stack_u64_push(&xs[nlines], 0); 79 stack_u64_push(&ys[nlines], maxy); 80 stack_u64_push(&xs[nlines], maxx); 81 stack_u64_push(&ys[nlines], maxy); 82 nlines++; 83 } 84 85 assert(minx > 0); // otherwise we would have to shift 86 assert(miny > 0); 87 88 uint8_t *grid = calloc((maxx + 1) * (maxy + 1), sizeof(*grid)); 89 90 for (i = 0; i < nlines; i++) { 91 assert(xs[i].nmemb == ys[i].nmemb); 92 for (j = 0; j < xs[i].nmemb - 1; j++) { 93 assert(xs[i].data[j] == xs[i].data[j + 1] || 94 ys[i].data[j] == ys[i].data[j + 1]); 95 if (xs[i].data[j] == xs[i].data[j + 1]) { 96 uint64_t x = xs[i].data[j]; 97 uint64_t yfrom = ys[i].data[j] < ys[i].data[j + 1] ? ys[i].data[j] 98 : ys[i].data[j + 1]; 99 uint64_t yto = ys[i].data[j] < ys[i].data[j + 1] ? ys[i].data[j + 1] 100 : ys[i].data[j]; 101 while (yfrom != yto) { 102 grid[x * (maxy + 1) + yfrom] = 1; 103 yfrom++; 104 } 105 grid[x * (maxy + 1) + yfrom] = 1; 106 } else { 107 uint64_t y = ys[i].data[j]; 108 uint64_t xfrom = xs[i].data[j] < xs[i].data[j + 1] ? xs[i].data[j] 109 : xs[i].data[j + 1]; 110 uint64_t xto = xs[i].data[j] < xs[i].data[j + 1] ? xs[i].data[j + 1] 111 : xs[i].data[j]; 112 while (xfrom != xto) { 113 grid[xfrom * (maxy + 1) + y] = 1; 114 xfrom++; 115 } 116 grid[xfrom * (maxy + 1) + y] = 1; 117 } 118 } 119 } 120 121 gd *r = malloc(sizeof(*r)); 122 r->h = (size_t)maxy + 1; 123 r->w = (size_t)maxx + 1; 124 r->minx = minx; 125 r->miny = miny; 126 r->maxx = maxx; 127 r->maxy = maxy; 128 r->grid = grid; 129 130 return r; 131 }