uppgb.c (1872B)
1 #include "common.h" 2 3 static inline int is_touching(int *hpos, int *tpos) { 4 if (abs(hpos[0] - tpos[0]) > 1 || abs(hpos[1] - tpos[1]) > 1) { 5 return 0; 6 } 7 return 1; 8 } 9 10 int make_move(int *pos, size_t npos, char move, smallset *s, int *boundaries) { 11 switch (move) { 12 case 'U': 13 pos[1]++; 14 break; 15 case 'D': 16 pos[1]--; 17 break; 18 case 'L': 19 pos[0]--; 20 break; 21 default: 22 pos[0]++; 23 break; 24 } 25 26 size_t i; 27 for (i = 0; i < 2 * npos - 2; i += 2) { 28 int *hpos = &pos[i]; 29 int *tpos = &pos[i + 2]; 30 if (!is_touching(hpos, tpos)) { 31 if (hpos[0] == tpos[0]) { 32 if (hpos[1] > tpos[1]) { 33 tpos[1]++; 34 } else { 35 tpos[1]--; 36 } 37 } else if (hpos[1] == tpos[1]) { 38 if (hpos[0] > tpos[0]) { 39 tpos[0]++; 40 } else { 41 tpos[0]--; 42 } 43 } else { 44 if (hpos[0] > tpos[0]) { 45 tpos[0]++; 46 } else { 47 tpos[0]--; 48 } 49 if (hpos[1] > tpos[1]) { 50 tpos[1]++; 51 } else { 52 tpos[1]--; 53 } 54 } 55 } 56 } 57 58 smallset_insert(s, diagon(&pos[2 * npos - 2], boundaries)); 59 60 return 0; 61 } 62 63 int main(int argc, char **argv) { 64 char **lines; 65 size_t nlines = readlines(&lines, "input"); 66 67 char *dirs = malloc(nlines * sizeof(*dirs)); 68 uint64_t *times = malloc(nlines * sizeof(*times)); 69 int boundaries[4]; 70 parse(boundaries, dirs, times, lines, nlines); 71 72 smallset s; 73 smallset_init(&s, (1 + boundaries[1] - boundaries[0]) * 74 (1 + boundaries[3] - boundaries[2])); 75 76 size_t npos = 10; 77 int pos[20] = {0}; 78 79 size_t i, j; 80 uint64_t jl; 81 for (i = 0; i < nlines; i++) { 82 sread_next_u64(&jl, lines[i]); 83 for (j = 0; j < jl; j++) { 84 make_move(pos, npos, lines[i][0], &s, boundaries); 85 } 86 } 87 88 printf("%llu\n", smallset_cardinality(&s)); 89 90 smallset_clear(&s); 91 }