uppgb.c (2401B)
1 #include "common.h" 2 3 typedef struct { 4 size_t identifier; 5 uint64_t value; 6 } adj_t; 7 8 static inline int is_digit(char x) { return '0' <= x && x <= '9'; } 9 10 static inline int update_adjacents(adj_t *adjs, const adj_t x) { 11 if (x.identifier) { 12 if (adjs[0].identifier == 0) { 13 adjs[0] = x; 14 } else if (adjs[0].identifier != x.identifier) { 15 if (adjs[1].identifier != 0) { 16 if (adjs[1].identifier != x.identifier) { 17 return 0; // more than 2 18 } 19 } else { 20 adjs[1] = x; 21 } 22 } 23 } 24 25 return 1; 26 } 27 28 static uint64_t gear_ratio(char **lines, const size_t i, const size_t j, 29 const size_t nrows, const size_t ncols, 30 adj_t *table) { 31 if (lines[i][j] != '*') 32 return 0; 33 34 adj_t adjs[2]; 35 adjs[0].identifier = 0; 36 adjs[1].identifier = 0; 37 38 coordinate_t ns[9]; 39 nbrs(ns, i, j, nrows, ncols); 40 41 size_t k = 0; 42 while (is_defined(ns[k])) { 43 if (!update_adjacents(adjs, table[ns[k].y * ncols + ns[k].x])) 44 return 0; 45 k++; 46 } 47 48 if (adjs[1].identifier != 0) { 49 return adjs[0].value * adjs[1].value; 50 } 51 52 return 0; 53 } 54 55 static inline void make_tables(adj_t *table, char **lines, const size_t nrows, 56 const size_t ncols) { 57 size_t count = 1; 58 uint64_t nnum = 0; 59 int innum = 0; 60 size_t i, j; 61 for (i = 0; i < nrows; i++) { 62 for (j = 0; j < ncols; j++) { 63 if (is_digit(lines[i][j])) { 64 if (nnum == 0) { 65 nnum = strtoull(&lines[i][j], NULL, 10); 66 } 67 table[i * ncols + j].value = nnum; 68 table[i * ncols + j].identifier = count; 69 innum = 1; 70 } else if (innum) { 71 count++; 72 innum = 0; 73 table[i * ncols + j].value = 0; 74 table[i * ncols + j].identifier = 0; 75 nnum = 0; 76 } else { 77 table[i * ncols + j].value = 0; 78 table[i * ncols + j].identifier = 0; 79 } 80 } 81 } 82 } 83 84 int main(int argc, char **argv) { 85 char **lines; 86 size_t nrows = readlines(&lines, "input"); 87 size_t ncols = strlen(lines[0]) - 1; 88 89 adj_t table[nrows * ncols]; 90 make_tables(table, lines, nrows, ncols); 91 92 size_t i, j; 93 uint64_t ratsum = 0; 94 for (i = 0; i < nrows; i++) { 95 for (j = 0; j < ncols; j++) { 96 uint64_t rat = gear_ratio(lines, i, j, nrows, ncols, table); 97 if (rat > 0) { 98 ratsum += rat; 99 } 100 } 101 } 102 103 printf("%llu\n", ratsum); 104 }