Day7 C
This commit is contained in:
BIN
day7/c/day7
Executable file
BIN
day7/c/day7
Executable file
Binary file not shown.
248
day7/c/day7.c
Normal file
248
day7/c/day7.c
Normal file
@@ -0,0 +1,248 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#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;
|
||||
}
|
||||
1000
day7/input.txt
Normal file
1000
day7/input.txt
Normal file
File diff suppressed because it is too large
Load Diff
5
day7/sample.txt
Normal file
5
day7/sample.txt
Normal file
@@ -0,0 +1,5 @@
|
||||
32T3K 765
|
||||
T55J5 684
|
||||
KK677 28
|
||||
KTJJT 220
|
||||
QQQJA 483
|
||||
Reference in New Issue
Block a user