#include #include #include #define DEFAULT_FILE "input.txt" #define STRBUF_LEN 200 #define ISDIGIT(X) (X >= '0' && X <= '9') typedef struct _hand { char cards[5]; // just for debugging int strength; int substrengths[5]; int bid; } hand; #define NUM_CARDS 13 #define NUM_HANDS 1000 const char strengthlist[NUM_CARDS] = { '2', '3', '4', '5', '6', '7', '8', '9', 'T', 'J', 'Q', 'K', 'A' }; // This function could be faster I'm sure. // Instead of searching through an array, // the characters could be mapped with // a lookup table. // I'm lazy to do this right now. int parse_substrength(char c) { int i = 0; for (i = 0; i < NUM_CARDS; i++) { if (c == strengthlist[i]) return i; } } int parse_strength(char *hand) { int hashmap[NUM_CARDS] = {0}; int i = 0; for (i = 0; i < 5; i++) { int substrength = parse_substrength(hand[i]); hashmap[substrength]++; } int most_duplicates = 0; int second_most_duplicates = 0; for (i = 0; i < NUM_CARDS; i++) { if (hashmap[i] >= most_duplicates) { second_most_duplicates = most_duplicates; most_duplicates = hashmap[i]; } else if (hashmap[i] >= second_most_duplicates) { second_most_duplicates = hashmap[i]; } } if (most_duplicates == 5) return 6; // Five of a kind if (most_duplicates == 4) return 5; // Four of a kind if (most_duplicates == 3 && second_most_duplicates == 2) return 4; // Full house if (most_duplicates == 3) return 3; // Three of a kind if (most_duplicates == 2 && second_most_duplicates == 2) return 2; // Two pair if (most_duplicates == 2) return 1; // Two of a kind return 0; } // Returns true if hand A beats hand B bool hand_beats(hand a, hand b) { if (a.strength != b.strength) return (a.strength > b.strength); int i = 0; for (i = 0; i < NUM_CARDS; i++) { if (a.substrengths[i] != b.substrengths[i]) { int suba = a.substrengths[i]; int subb = b.substrengths[i]; bool a_beats_b = suba > subb; return (a_beats_b); } } return false; } int parse_num(char *str) { int num = 0; while (ISDIGIT(*str)) { num = (num * 10) + (*str - '0'); str++;int strength[1000] = {0}; int payout[1000] = {0}; } return num; } void sort(hand *hands) { // Insertion sort, because I'm too lazy. // Other sorting algorithms would be faster. // Try quicksort. int a = 0; int b = 0; for (a = NUM_HANDS - 1; a >= 0; a--) { for (b = NUM_HANDS - 1; b >= a; b--) { if (hand_beats(hands[a], hands[b])) { hand h = hands[a]; hands[a] = hands[b]; hands[b] = h; } } } } int main(int argc, char **argv) { // Get filename as an argument, if there is one char *path = (argc > 1) ? argv[1] : DEFAULT_FILE; if (!path) { printf("Requires input file.\n"); return 1; } FILE *file = fopen(path, "r"); char strbuf[STRBUF_LEN] = {0}; if (!file) { printf("Could not find file."); return 1; } // ************************************ // Begin Challenge // ************************************ hand hands[NUM_HANDS]; hand sorted_hands[NUM_HANDS]; uint16_t i = 0; uint16_t k = 0; while (fgets(strbuf, STRBUF_LEN, file)) { hands[i].strength = parse_strength(strbuf); for (k = 0; k < 5; k++) { hands[i].cards[k] = strbuf[k]; hands[i].substrengths[k] = parse_substrength(strbuf[k]); } hands[i].bid = parse_num(strbuf + 6); i++; } printf("\n"); sort(hands); uint64_t winnings = 0; for (i = NUM_HANDS - 1; i <= NUM_HANDS; i--) { printf("%c%c%c%c%c", hands[i].cards[0], hands[i].cards[1], hands[i].cards[2], hands[i].cards[3], hands[i].cards[4]); printf(" i: %.3d str: %.2d, %.2d %.2d %.2d %.2d %.2d, bid: %.3d\n", i + 1, hands[i].strength, hands[i].substrengths[0], hands[i].substrengths[1], hands[i].substrengths[2], hands[i].substrengths[3], hands[i].substrengths[4], hands[i].bid ); winnings += hands[i].bid * (i + 1); } printf("winnings: %lu\n", winnings); return 0; }