uppgb.c (2463B)
1 #include "common.h" 2 3 static inline uint64_t hash(char *s) { 4 uint64_t v = 0; 5 char *cp = s; 6 7 while (*cp != '\0' && *cp != '-' && *cp != '=') { 8 v = (17 * (v + ((uint64_t)*cp))) & 0xff; 9 cp++; 10 } 11 12 return v; 13 } 14 15 static inline stack_str parse(char *line) { 16 char *cp = line; 17 18 stack_str stack; 19 stack_str_init(&stack); 20 21 while (*cp != '\0' && *cp != '\n') { 22 stack_str_push(&stack, cp); 23 while (*cp != '\0' && *cp != '\n' && *cp != ',') { 24 cp++; 25 } 26 cp++; 27 } 28 29 return stack; 30 } 31 32 static inline char opn(char *s) { 33 char *c = s; 34 while (*c != '-' && *c != '=') 35 c++; 36 37 return *c; 38 } 39 40 static inline int cmp(char *s, char *t) { 41 char *cs = s; 42 char *ct = t; 43 44 while (*cs != '-' && *cs != '=' && *ct != '-' && *ct != '=') { 45 if (*cs != *ct) 46 return 1; 47 cs++; 48 ct++; 49 } 50 51 if (*cs == '=' && *ct == '-') 52 return 0; 53 54 if (*cs != *ct) 55 return 1; 56 57 return 0; 58 } 59 60 typedef TAILQ_HEAD(listhead, entry) lhead_t; 61 62 typedef struct entry { 63 char *s; 64 uint64_t fl; 65 TAILQ_ENTRY(entry) entries; 66 } entry_t; 67 68 static inline void doop(char op, char *s, lhead_t *box) { 69 if (op == '-') { 70 entry_t *np; 71 TAILQ_FOREACH(np, box, entries) { 72 if (cmp(np->s, s) == 0) { 73 // remove np from list 74 TAILQ_REMOVE(box, np, entries); 75 free(np); 76 return; 77 } 78 } 79 } else { 80 uint64_t fl; 81 sread_next_u64(&fl, s); 82 entry_t *np; 83 TAILQ_FOREACH(np, box, entries) { 84 if (cmp(np->s, s) == 0) { 85 // CHANGE np 86 np->s = s; 87 np->fl = fl; 88 return; 89 } 90 } 91 92 // was not in list, add it to the end 93 entry_t *ne = malloc(sizeof(entry_t)); 94 ne->s = s; 95 ne->fl = fl; 96 TAILQ_INSERT_TAIL(box, ne, entries); 97 } 98 } 99 100 static inline uint64_t boxval(lhead_t *box) { 101 entry_t *np; 102 uint64_t slot = 1; 103 uint64_t v = 0; 104 105 TAILQ_FOREACH(np, box, entries) { 106 v += slot * (np->fl); 107 slot++; 108 } 109 110 return v; 111 } 112 113 int main(int argc, char **argv) { 114 char **lines; 115 size_t i; 116 readlines(&lines, "input"); 117 118 stack_str ops = parse(lines[0]); 119 120 // initialize dlinked lists 121 lhead_t lls[256]; 122 for (i = 0; i < 256; i++) { 123 TAILQ_INIT(&lls[i]); 124 } 125 126 // operational state 127 for (i = 0; i < ops.nmemb; i++) { 128 uint64_t box = hash(ops.data[i]); 129 doop(opn(ops.data[i]), ops.data[i], &lls[box]); 130 } 131 132 // count sum 133 uint64_t summa = 0; 134 for (i = 0; i < 256; i++) { 135 summa += (i + 1) * boxval(&lls[i]); 136 } 137 138 printf("%llu\n", summa); 139 }