#include #include #include #define LINE_MAX_LENGTH 64 #define MAX_HANDS 2048 #define CARDS_PER_HAND 5 enum hand_type { UNKNOWN, FIVE_OF_A_KIND, FOUR_OF_A_KIND, FULL_HOUSE, THREE_OF_A_KIND, TWO_PAIR, ONE_PAIR, HIGH_CARD }; const char card_values[] = {'A', 'K', 'Q', 'J', 'T', '9', '8', '7', '6', '5', '4', '3', '2'}; const char card_values2[] = {'A', 'K', 'Q', 'T', '9', '8', '7', '6', '5', '4', '3', '2', 'J'}; #define card_values_len (sizeof(card_values) / sizeof(card_values[0])) typedef struct hand { char cards[CARDS_PER_HAND]; unsigned long bid; enum hand_type type; } hand_t; enum hand_type get_hand_type(hand_t *hand, int allow_joker); int cmp(const void *a, const void *b); int cmp2(const void *a, const void *b); int main() { char *p, *buf, c; buf = (char *)malloc(LINE_MAX_LENGTH); memset(buf, 0, LINE_MAX_LENGTH); p = buf; hand_t hands[MAX_HANDS]; memset(hands, 0, MAX_HANDS * sizeof(hand_t)); int hands_num = 0; while ((c = getchar()) != EOF) { *p++ = c; if (c == '\n') { p = buf; sscanf(p, "%c%c%c%c%c %lu", &hands[hands_num].cards[0], &hands[hands_num].cards[1], &hands[hands_num].cards[2], &hands[hands_num].cards[3], &hands[hands_num].cards[4], &hands[hands_num].bid); hands_num++; memset(buf, 0, LINE_MAX_LENGTH); p = buf; } } // Part1 for (int i = 0; i < hands_num; i++) { hands[i].type = get_hand_type(&hands[i], 0); } qsort(hands, hands_num, sizeof(hand_t), cmp); unsigned long part1 = 0; for (int i = 0; i < hands_num; i++) { part1 += (i+1) * hands[i].bid; } printf("%lu\n", part1); // Part2 for (int i = 0; i < hands_num; i++) { hands[i].type = get_hand_type(&hands[i], 1); } qsort(hands, hands_num, sizeof(hand_t), cmp2); unsigned long part2 = 0; for (int i = 0; i < hands_num; i++) { part2 += (i+1) * hands[i].bid; } printf("%lu\n", part2); free(buf); } enum hand_type get_hand_type(hand_t *hand, int allow_joker) { // Five of a kind int good = 0; for (int i = 0; i < CARDS_PER_HAND; i++) { good = 0; for (int j = 0; j < CARDS_PER_HAND; j++) { if (hand->cards[i] == hand->cards[j] || (allow_joker && hand->cards[j] == 'J')) { good++; } } if (good == 5) { return FIVE_OF_A_KIND; } } // Four of a kind for (int i = 0; i < CARDS_PER_HAND; i++) { good = 0; for (int j = 0; j < CARDS_PER_HAND; j++) { if (hand->cards[i] == hand->cards[j] || (allow_joker && hand->cards[j] == 'J')) { good++; } } if (good == 4) { return FOUR_OF_A_KIND; } } // Full house int good2 = 0; for (int i = 0; i < CARDS_PER_HAND; i++) { for (int j = 0; j < CARDS_PER_HAND; j++) { good = 0; good2 = 0; int used_jokers[5] = {0, 0, 0, 0, 0}; for (int k = 0; k < CARDS_PER_HAND; k++) { if (hand->cards[i] == hand->cards[k] || (allow_joker && !used_jokers[k] && hand->cards[k] == 'J')) { good++; if (allow_joker && hand->cards[k] == 'J') { used_jokers[k] = 1; } } } for (int k = 0; k < CARDS_PER_HAND; k++) { if (hand->cards[j] == hand->cards[k] || (allow_joker && !used_jokers[k] && hand->cards[k] == 'J')) { good2++; } } if ((good == 3 && good2 == 2 || good == 2 && good2 == 3) && hand->cards[i] != 'J' && hand->cards[j] != 'J' && hand->cards[i] != hand->cards[j]) { return FULL_HOUSE; } } } // Three of a kind for (int i = 0; i < CARDS_PER_HAND; i++) { good = 0; for (int j = 0; j < CARDS_PER_HAND; j++) { if (hand->cards[i] == hand->cards[j] || (allow_joker && hand->cards[j] == 'J')) { good++; } } if (good == 3) { return THREE_OF_A_KIND; } } // Two pair for (int i = 0; i < CARDS_PER_HAND; i++) { for (int j = 0; j < CARDS_PER_HAND; j++) { good = 0; good2 = 0; int used_joker = 0; for (int k = 0; k < CARDS_PER_HAND; k++) { if (hand->cards[i] == hand->cards[k] || (allow_joker && hand->cards[k] == 'J')) { good++; if (allow_joker && hand->cards[k] == 'J') { used_joker = 1; } } } for (int k = 0; k < CARDS_PER_HAND; k++) { if (hand->cards[j] == hand->cards[k] || (allow_joker && !used_joker && hand->cards[k] == 'J')) { good2++; } } if (good == 2 && good2 == 2 && hand->cards[i] != hand->cards[j]) { return TWO_PAIR; } } } // One pair for (int i = 0; i < CARDS_PER_HAND; i++) { good = 0; for (int j = 0; j < CARDS_PER_HAND; j++) { if (hand->cards[i] == hand->cards[j] || (allow_joker && hand->cards[j] == 'J')) { good++; } } if (good == 2) { return ONE_PAIR; } } return HIGH_CARD; } int cmp(const void *a, const void *b) { hand_t *hand1 = (hand_t*) a, *hand2 = (hand_t*) b; if (hand1->type == hand2->type) { for (int i = 0; i < CARDS_PER_HAND; i++) { int j, k; for (j = 0; j < card_values_len; j++) { if (hand1->cards[i] == card_values[j]) { break; } } for (k = 0; k < card_values_len; k++) { if (hand2->cards[i] == card_values[k]) { break; } } if (j != k) { return k - j; } } } return hand2->type - hand1->type; } int cmp2(const void *a, const void *b) { hand_t *hand1 = (hand_t*) a, *hand2 = (hand_t*) b; if (hand1->type == hand2->type) { for (int i = 0; i < CARDS_PER_HAND; i++) { int j, k; for (j = 0; j < card_values_len; j++) { if (hand1->cards[i] == card_values2[j]) { break; } } for (k = 0; k < card_values_len; k++) { if (hand2->cards[i] == card_values2[k]) { break; } } if (j != k) { return k - j; } } } return hand2->type - hand1->type; }