From d3a49dd06f217c0656ab89c6804ab1e525e4785b Mon Sep 17 00:00:00 2001 From: nalydmerc Date: Thu, 7 Dec 2023 22:57:37 -0500 Subject: [PATCH] Complete Day 7 Part 2 --- 07/07-part2.c | 209 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 209 insertions(+) create mode 100644 07/07-part2.c diff --git a/07/07-part2.c b/07/07-part2.c new file mode 100644 index 0000000..61e3478 --- /dev/null +++ b/07/07-part2.c @@ -0,0 +1,209 @@ +#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] = { 'J', '2', '3', '4', '5', '6', '7', '8', '9', 'T', '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 = 1; 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]; + } + } + + int js = hashmap[0]; + + // I'm sure there's a better way to do this. + if (most_duplicates == 5) return 6; // Five of a kind + if (most_duplicates + js == 5) return 6; // Five of a kind, jokers + + if (most_duplicates == 4) return 5; // Four of a kind + if (most_duplicates + js == 4) return 5; // Four of a kind, jokers + + if (most_duplicates == 3 && second_most_duplicates == 2) return 4; // Full house + if (most_duplicates == 2 && second_most_duplicates == 2 && js == 1) return 4; // Full house, jokers + if (most_duplicates == 3 && second_most_duplicates == 1 && js == 1) return 4; // Full house, jokers + + if (most_duplicates == 3) return 3; // Three of a kind + if (most_duplicates + js == 3) return 3; // Three of a kind + + if (most_duplicates == 2 && second_most_duplicates == 2) return 2; // Two pair + if (most_duplicates == 2 && second_most_duplicates + js == 2) return 2; // Two pair + + if (most_duplicates + js == 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; +} \ No newline at end of file