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