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