uppga.c (2789B)
1 #include "common.h" 2 3 typedef struct { 4 size_t na; 5 size_t nb; 6 } pos_t; 7 8 static inline pos_t compute_nbrs(size_t row, size_t col, char **lines, 9 size_t nrows, size_t ncols) { 10 pos_t r; 11 12 switch (lines[row][col]) { 13 case '|': 14 if (row == 0 || row == nrows - 1) { 15 r.na = SIZE_MAX; 16 r.nb = SIZE_MAX; 17 } else { 18 r.na = (row - 1) * ncols + col; 19 r.nb = (row + 1) * ncols + col; 20 } 21 break; 22 case '-': 23 if (col == 0 || col == ncols - 1) { 24 r.na = SIZE_MAX; 25 r.nb = SIZE_MAX; 26 } else { 27 r.na = row * ncols + col - 1; 28 r.nb = row * ncols + col + 1; 29 } 30 break; 31 case 'F': 32 if (col == ncols - 1 || row == nrows - 1) { 33 r.na = SIZE_MAX; 34 r.nb = SIZE_MAX; 35 } else { 36 r.na = row * ncols + col + 1; 37 r.nb = (row + 1) * ncols + col; 38 } 39 break; 40 case '7': 41 if (col == 0 || row == nrows - 1) { 42 r.na = SIZE_MAX; 43 r.nb = SIZE_MAX; 44 } else { 45 r.na = row * ncols + col - 1; 46 r.nb = (row + 1) * ncols + col; 47 } 48 break; 49 case 'L': 50 if (col == ncols - 1 || row == 0) { 51 r.na = SIZE_MAX; 52 r.nb = SIZE_MAX; 53 } else { 54 r.na = (row - 1) * ncols + col; 55 r.nb = row * ncols + col + 1; 56 } 57 break; 58 case 'J': 59 if (col == 0 || row == 0) { 60 r.na = SIZE_MAX; 61 r.nb = SIZE_MAX; 62 } else { 63 r.na = (row - 1) * ncols + col; 64 r.nb = row * ncols + col - 1; 65 } 66 break; 67 default: // S or . 68 r.na = SIZE_MAX; 69 r.nb = SIZE_MAX; 70 } 71 72 return r; 73 } 74 75 static inline size_t traverse(size_t start, size_t next, pos_t *ns) { 76 size_t head = next; 77 size_t tail = start; 78 size_t steps = 0; 79 80 if (ns[head].na != tail && ns[head].nb != tail) { 81 return SIZE_MAX; 82 } 83 84 while (head != start && ns[head].na != SIZE_MAX) { 85 size_t tmp = head; 86 if (ns[head].na == tail) { 87 head = ns[head].nb; 88 } else { 89 head = ns[head].na; 90 } 91 tail = tmp; 92 steps++; 93 } 94 95 if (head == start) 96 return steps; 97 98 return SIZE_MAX; 99 } 100 101 int main(int argc, char **argv) { 102 char **lines; 103 size_t i, j; 104 size_t nlines = readlines(&lines, "input"); 105 106 size_t ncols = strlen(lines[0]) - 1; 107 108 size_t start; 109 pos_t ns[nlines * ncols]; 110 for (i = 0; i < nlines; i++) { 111 for (j = 0; j < ncols; j++) { 112 ns[i * ncols + j] = compute_nbrs(i, j, lines, nlines, ncols); 113 if (lines[i][j] == 'S') { 114 start = i * ncols + j; 115 } 116 } 117 } 118 119 size_t r; 120 if ((r = traverse(start, start + 1, ns)) != SIZE_MAX) { 121 printf("%zu\n", (r + 1) / 2); 122 } else if ((r = traverse(start, start - 1, ns)) != SIZE_MAX) { 123 printf("%zu\n", (r + 1) / 2); 124 } else if ((r = traverse(start, start + ncols, ns)) != SIZE_MAX) { 125 printf("%zu\n", (r + 1) / 2); 126 } else { 127 printf("bad\n"); 128 } 129 }