uppgb.c (2382B)
1 #include "common.h" 2 3 #define ZZZ 17575 4 #define AAA 0 5 6 static inline stack_u64 read_starts(char **lines, size_t nlines) { 7 size_t i; 8 stack_u64 r; 9 stack_u64_init(&r); 10 11 for (i = 2; i < nlines; i++) { 12 if (lines[i][2] == 'A') { 13 stack_u64_push(&r, chrs_to_node(lines[i])); 14 } 15 } 16 17 return r; 18 } 19 20 // positition = (value, ins) where 0 <= ins < #instructions 21 typedef struct { 22 uint64_t v; 23 size_t ins; 24 } pos_t; 25 26 typedef struct { 27 uint64_t *ls; 28 uint64_t *rs; 29 30 char *ins; 31 size_t nins; 32 } gr_t; 33 34 static inline pos_t stepf(pos_t x, gr_t *g) { 35 pos_t r; 36 r.ins = (x.ins + 1) % g->nins; 37 if (g->ins[x.ins] == 'L') { 38 r.v = g->ls[x.v]; 39 } else { 40 r.v = g->rs[x.v]; 41 } 42 43 return r; 44 } 45 46 static inline void floyd(stack_u64 *mus, stack_u64 *lams, pos_t s, gr_t *g) { 47 pos_t tortoise = stepf(s, g); 48 pos_t hare = stepf(tortoise, g); 49 50 while (tortoise.v != hare.v || tortoise.ins != hare.ins) { 51 tortoise = stepf(tortoise, g); 52 hare = stepf(stepf(hare, g), g); 53 } 54 55 uint64_t mu = 0; 56 tortoise = s; 57 while (tortoise.v != hare.v || tortoise.ins != hare.ins) { 58 tortoise = stepf(tortoise, g); 59 hare = stepf(hare, g); 60 mu++; 61 } 62 63 uint64_t lam = 1; 64 hare = stepf(tortoise, g); 65 while (tortoise.v != hare.v || tortoise.ins != hare.ins) { 66 hare = stepf(hare, g); 67 lam++; 68 } 69 70 stack_u64_push(mus, mu); 71 stack_u64_push(lams, lam); 72 } 73 74 static uint64_t lcm(stack_u64 *s) { 75 mpz_t l, t1; 76 mpz_inits(l, t1, NULL); 77 mpz_set_ui(l, s->data[0]); 78 79 size_t i; 80 for (i = 1; i < s->nmemb; i++) { 81 mpz_set_ui(t1, s->data[i]); 82 mpz_lcm(l, l, t1); 83 } 84 85 uint64_t r = mpz_get_ui(l); 86 87 mpz_clears(l, t1, NULL); 88 89 return r; 90 } 91 92 int main(int argc, char **argv) { 93 size_t i, nins = 0; 94 char **lines; 95 size_t nlines = readlines(&lines, "input"); 96 97 char *instructions = lines[0]; 98 while (instructions[nins] == 'R' || instructions[nins] == 'L') { 99 nins++; 100 } 101 102 uint64_t lefts[ZZZ + 1]; 103 uint64_t rights[ZZZ + 1]; 104 read_graph(lefts, rights, lines, nlines); 105 106 gr_t g = {lefts, rights, instructions, nins}; 107 108 stack_u64 starts = read_starts(lines, nlines); 109 stack_u64 mus, lams; 110 stack_u64_init(&mus); 111 stack_u64_init(&lams); 112 113 for (i = 0; i < starts.nmemb; i++) { 114 pos_t first = {starts.data[i], 0}; 115 floyd(&mus, &lams, first, &g); 116 } 117 118 uint64_t lcm_lam = lcm(&lams); 119 printf("%llu\n", lcm_lam); 120 121 stack_u64_clear(&starts); 122 }