195 lines
4.7 KiB
C
195 lines
4.7 KiB
C
#include <stdio.h>
|
|
#include <stdint.h>
|
|
#include <stdbool.h>
|
|
|
|
#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;
|
|
} |