uppgb.c (2341B)
1 #include "common.h" 2 3 int cmp(const void *a, const void *b); 4 5 int cmp(const void *a, const void *b) { 6 size_t i; 7 8 hand_t ha = *(const hand_t *)a; 9 hand_t hb = *(const hand_t *)b; 10 11 uint64_t ha_val = ha.maxval; 12 uint64_t hb_val = hb.maxval; 13 14 if (ha_val != hb_val) { 15 if (ha_val < hb_val) 16 return -1; 17 else 18 return 1; 19 } else { 20 for (i = 0; i < 5; i++) { 21 if (ha.cards[i] != hb.cards[i]) { 22 if (ha.cards[i] < hb.cards[i]) 23 return -1; 24 else 25 return 1; 26 } 27 } 28 } 29 30 return 0; 31 } 32 33 static inline uint8_t char_to_card(const char c) { 34 if ('2' <= c && c <= '9') 35 return (uint8_t)(c - '0'); 36 switch (c) { 37 case 'T': 38 return 10; 39 case 'J': 40 return 1; 41 case 'Q': 42 return 12; 43 case 'K': 44 return 13; 45 case 'A': 46 return 14; 47 default: 48 exit(1); 49 } 50 } 51 52 static inline int all_jokers_are_aces(hand_t *t, hand_t *h) { 53 size_t i; 54 55 for (i = 0; i < 5; i++) { 56 if (h->cards[i] == 1 && t->cards[i] != 14) 57 return 0; 58 } 59 60 return 1; 61 } 62 63 static inline void increment_jokers(hand_t *t, hand_t *h) { 64 size_t i; 65 66 for (i = 0; i < 5; i++) { 67 if (h->cards[i] == 1) { 68 if (t->cards[i] != 14) { 69 t->cards[i]++; 70 return; 71 } else { 72 t->cards[i] = 2; 73 } 74 } 75 } 76 } 77 78 static inline uint64_t find_max_val(hand_t h) { 79 uint64_t maxval = 0; 80 uint64_t tmpval; 81 hand_t t = h; 82 83 size_t i; 84 for (i = 0; i < 5; i++) { 85 if (t.cards[i] == 1) 86 t.cards[i] = 2; 87 } 88 89 while (!all_jokers_are_aces(&t, &h)) { 90 tmpval = hand_value(t); 91 if (tmpval > maxval) 92 maxval = tmpval; 93 increment_jokers(&t, &h); 94 } 95 96 tmpval = hand_value(t); 97 if (tmpval > maxval) 98 maxval = tmpval; 99 100 return maxval; 101 } 102 103 static inline void read_hands(hand_t *h, char **lines, const size_t nlines) { 104 size_t i, j; 105 106 for (i = 0; i < nlines; i++) { 107 for (j = 0; j < 5; j++) 108 h[i].cards[j] = char_to_card(lines[i][j]); 109 sread_next_u64(&(h[i].bid), &lines[i][6]); 110 h[i].maxval = find_max_val(h[i]); 111 } 112 } 113 114 int main(int argc, char **argv) { 115 char **lines; 116 size_t nlines = readlines(&lines, "input"); 117 118 hand_t h[nlines]; 119 read_hands(h, lines, nlines); 120 121 qsort(h, nlines, sizeof(h[0]), cmp); 122 123 uint64_t m; 124 uint64_t sum = 0; 125 for (m = 0; m < nlines; m++) { 126 sum += (m + 1) * h[m].bid; 127 } 128 129 printf("%llu\n", sum); 130 }