common.c (2961B)
1 #include "common.h" 2 3 monkis parse_monkis(char **lines, size_t nlines, int mods) { 4 monkis r; 5 size_t i, j; 6 uint64_t t; 7 8 r.mod = malloc(nlines * sizeof(*r.mod)); 9 10 r.n = 0; 11 r.nitems = 0; 12 for (i = 0; i < nlines; i++) { 13 if (lines[i][0] == 'M') 14 r.n++; 15 else if (strlen(lines[i]) > 2) { 16 if (lines[i][2] == 'S') { 17 char *p = lines[i]; 18 while ((p = sread_next_u64(&t, p)) != NULL) 19 r.nitems++; 20 } else if (lines[i][2] == 'T') { 21 sread_next_u64(&(r.mod[r.n - 1]), lines[i]); 22 } 23 } 24 } 25 26 r.mod = realloc(r.mod, r.n * sizeof(*r.mod)); 27 28 r.rmod = malloc(r.n * sizeof(*r.rmod)); 29 memcpy(r.rmod, r.mod, r.n * sizeof(*r.rmod)); 30 if (!mods) 31 for (i = 0; i < r.n; i++) 32 r.mod[i] = UINT64_MAX; 33 34 r.fnext = malloc(r.n * sizeof(*r.fnext)); 35 r.tnext = malloc(r.n * sizeof(*r.tnext)); 36 r.heads = malloc(r.n * sizeof(*r.heads)); 37 38 r.inspections = calloc(r.n, sizeof(*r.inspections)); 39 40 r.items = malloc(r.nitems * r.n * sizeof(*r.items)); 41 42 size_t cm = 0, ci = 0; 43 for (i = 0; i < nlines; i++) { 44 if (strlen(lines[i]) > 2) { 45 if (lines[i][4] == 'I') { 46 sread_next_u64(&t, lines[i]); 47 if (lines[i][7] == 't') 48 r.tnext[cm] = t; 49 else 50 r.fnext[cm] = t; 51 } else if (lines[i][2] == 'S') { 52 SIMPLEQ_INIT(&r.heads[cm]); 53 char *p = lines[i]; 54 while ((p = sread_next_u64(&t, p)) != NULL) { 55 struct entry *new_entry = malloc(sizeof(*new_entry)); 56 new_entry->index = ci; 57 SIMPLEQ_INSERT_TAIL(&r.heads[cm], new_entry, entries); 58 for (j = 0; j < r.n; j++) 59 r.items[ci * r.n + j] = t % r.mod[j]; 60 ci++; 61 } 62 } 63 } else { 64 cm++; 65 } 66 } 67 return r; 68 } 69 70 void mmonkey(monkis m, size_t i) { 71 uint64_t *tmp; 72 struct entry *np; 73 size_t j; 74 75 while (!SIMPLEQ_EMPTY(&m.heads[i])) { 76 m.inspections[i]++; 77 np = SIMPLEQ_FIRST(&m.heads[i]); 78 SIMPLEQ_REMOVE_HEAD(&m.heads[i], entries); 79 tmp = &(m.items[np->index * m.n]); 80 for (j = 0; j < m.n; j++) 81 tmp[j] = (m.operate)(tmp[j], i) % m.mod[j]; 82 83 size_t new_index = (tmp[i] % m.rmod[i]) == 0 ? m.tnext[i] : m.fnext[i]; 84 85 SIMPLEQ_INSERT_TAIL(&m.heads[new_index], np, entries); 86 } 87 } 88 89 void mround(monkis m) { 90 size_t i; 91 for (i = 0; i < m.n; i++) 92 mmonkey(m, i); 93 } 94 95 uint64_t get_result(monkis m) { 96 uint64_t tmax[2] = {0, 0}; 97 98 size_t i; 99 for (i = 0; i < m.n; i++) { 100 if (m.inspections[i] > tmax[0]) 101 tmax[0] = m.inspections[i]; 102 if (tmax[0] > tmax[1]) 103 tmax[0] ^= tmax[1] ^= tmax[0] ^= tmax[1]; 104 } 105 106 return tmax[0] * tmax[1]; 107 } 108 109 void let_the_monkis_out(monkis m) { 110 free(m.mod); 111 free(m.tnext); 112 free(m.fnext); 113 114 free(m.items); 115 116 size_t i; 117 struct entry *t; 118 for (i = 0; i < m.n; i++) { 119 while (!SIMPLEQ_EMPTY(&m.heads[i])) { 120 t = SIMPLEQ_FIRST(&m.heads[i]); 121 SIMPLEQ_REMOVE_HEAD(&m.heads[i], entries); 122 free(t); 123 } 124 } 125 free(m.heads); 126 }