10315 - Poker Hands

All about problems in Volume 103. If there is a thread about your problem, please use it. If not, create one with its number in the subject.

Moderator: Board moderators

mohdali231993
New poster
Posts: 11
Joined: Sun Nov 09, 2014 6:46 pm

Re: 10315 - Poker Hands

Post by mohdali231993 »

help me out guys
i've checked all samples but still wrong answer from the judge
brianfry713
Guru
Posts: 5947
Joined: Thu Sep 01, 2011 9:09 am
Location: San Jose, CA, USA

Re: 10315 - Poker Hands

Post by brianfry713 »

Try input:
3D 3H 4D 4H 2S 5C 5S AH KD QC

Output should be
Black wins.
Check input and AC output for thousands of problems on uDebug!
agrskk2
New poster
Posts: 2
Joined: Mon Apr 27, 2015 3:13 pm

Re: 10315 - Poker Hands

Post by agrskk2 »

Hello,

my solution is passing all the cases that ar posted in this thread and I checked with my own cases that were made for each cobination I could think of, but still getting WA.

Could somone provide some tricky test cases or any other clues?

Thanks.
agrskk2
New poster
Posts: 2
Joined: Mon Apr 27, 2015 3:13 pm

Re: 10315 - Poker Hands

Post by agrskk2 »

Here is the code.

Code: Select all

/*
 * UVa Online Judge 
 * 10315 - Poker Hands
 * Ad-Hoc - Game
 */
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>

typedef enum {
	BLACK = 0,
	WHITE = 1,
	PLAYER_COUNT,
	TIE,
} player;

typedef enum {
	HIGH_CARD, PAIR, TWO_PAIRS, THREE_OF_A_KIND,
	STRAIGHT, FLUSH, FULL_HOUSE, FOUR_OF_A_KIND,
	STRAIGHT_FLUSH,
} hand;

typedef enum {
	CARD_2  = 2,  CARD_3 = 3,  CARD_4 = 4,  CARD_5 = 5,
	CARD_6  = 6,  CARD_7 = 7,  CARD_8 = 8,  CARD_9 = 9,
	CARD_10 = 10, CARD_J = 11, CARD_Q = 12, CARD_K = 13,
	CARD_A  = 14
} card_value;

unsigned int sym_to_num[] = {
	['2'] = CARD_2,  ['3'] = CARD_3, ['4'] = CARD_4, ['5'] = CARD_5,
	['6'] = CARD_6,  ['7'] = CARD_7, ['8'] = CARD_8, ['9'] = CARD_9,
	['T'] = CARD_10, ['J'] = CARD_J, ['Q'] = CARD_Q, ['K'] = CARD_K,
	['A'] = CARD_A,
};

#define CARDS_PLAYER 5
#define SYM_PER_CARD 3

#define VALUE_NDX    0
#define SUIT_NDX     1

#define MAX_POSSIBLE_PAIRS 2


struct poker_hand {
	char cards[CARDS_PLAYER * SYM_PER_CARD];
	bool seen[CARDS_PLAYER];

	size_t pairs;
	char pair_values[MAX_POSSIBLE_PAIRS];

	size_t same_cnt;
	char same_value;
};

/* ----------- DEBUG -------------- */

void print_hand(struct poker_hand *h)
{
	printf("Cards: ");
	size_t i, j;
	for (i = 0; i < CARDS_PLAYER; ++i) {
		char *card = h->cards + (i * SYM_PER_CARD);
		if (h->seen[i]) printf("[%s] ", card);
		else printf("%s ", card);
	}
	printf("\n---\n");
	printf("Pairs: %ld", h->pairs);
	if (h->pairs > 0) {
		printf("  ");
		for (j = 0; j < h->pairs; ++j)
			printf("[%c] ", h->pair_values[j]);
	}
	printf("\nSame: %ld", h->same_cnt);
	if (h->same_cnt > 0) {
		printf(" [%c]", h->same_value);
	}
	printf("\n");
}

void print_players(struct poker_hand *players)
{
	printf("---------------------------------------\n");
	printf("   -= BLACK =-   \n");
	print_hand(&players[BLACK]);
	printf("\n   -= WHITE =-  \n");
	print_hand(&players[WHITE]);
	printf("---------------------------------------\n");
}

void print_hands(char cards[2][5][3])
{
	printf("--- Black ---     --- White ---\n");
	size_t i, j;
	for (i = 0; i < PLAYER_COUNT; ++i) {
		for (j = 0; j < CARDS_PLAYER; ++j) {
			printf("%s ", cards[i][j]);
		}
		printf("  ");
	}
	printf("\n");
}
/* ----------- END OF DEBUG -------------- */

int compare_ints(const void *a, const void *b)
{
	return *(int *)a - *(int *)b;
}

bool get_is_straight(struct poker_hand *player_hand)
{
	size_t matches = 0;
	unsigned int next_card = sym_to_num[player_hand->cards[VALUE_NDX]];

	size_t i;
	for (i = 0; i < CARDS_PLAYER; ++i) {
		if (next_card > CARD_A) break;
		if (next_card++ !=
			sym_to_num[(player_hand->cards + i * SYM_PER_CARD)[VALUE_NDX]]) break;
		++matches;
	}

	return (matches == CARDS_PLAYER);
}

bool get_is_flush(struct poker_hand *player_hand)
{
	size_t same_suit = 1;
	char suit = player_hand->cards[SUIT_NDX];

	size_t i;
	for (i = 1; i < CARDS_PLAYER; ++i) {
		if ((player_hand->cards + (i * SYM_PER_CARD))[SUIT_NDX] == suit) ++same_suit;
	}

	return (same_suit == CARDS_PLAYER);
}

int compare_cards(const void *a, const void *b)
{
	char *card_a = (char *)a;
	char *card_b = (char *)b;

	return sym_to_num[card_a[0]] - sym_to_num[card_b[0]];
}

void count_same(struct poker_hand *player_hand)
{
	bool same_locations[CARDS_PLAYER];

	size_t i, j, k;
	for (i = 0; i < CARDS_PLAYER; ++i) {
		if (player_hand->seen[i]) continue;
		memset(same_locations, 0, sizeof(bool) * CARDS_PLAYER);

		char current_card = (player_hand->cards + i * SYM_PER_CARD)[VALUE_NDX];
		same_locations[i] = true;
		size_t same_cnt = 1;

		/* the actual counting */
		for (j = 0; j < CARDS_PLAYER; ++j) {
			if (player_hand->seen[i] || i == j) continue;
			if (current_card == (player_hand->cards + j * SYM_PER_CARD)[VALUE_NDX]) {
				same_locations[j] = true;
				++same_cnt;
			}
		}

		/* assign counts */
		if (same_cnt >= 2) {
			for (k = 0; k < CARDS_PLAYER; ++k) {
				if ( !player_hand->seen[k]) {
					player_hand->seen[k] = same_locations[k];
				}
			}

			if (same_cnt > 2 && same_cnt > player_hand->same_cnt) {
				player_hand->same_cnt = same_cnt;
				player_hand->same_value = current_card;
			}
			else if (same_cnt == 2) {
				player_hand->pair_values[player_hand->pairs++] = current_card;
			}
		}
	}
}

hand player_hand_rank(struct poker_hand *player_hand)
{
	qsort(player_hand->cards, CARDS_PLAYER,
		  sizeof(char) * SYM_PER_CARD,
		  compare_cards);

	count_same(player_hand);
	bool is_straight = get_is_straight(player_hand);
	bool is_flush    = get_is_flush(player_hand);

	if (is_straight && is_flush)
		return STRAIGHT_FLUSH;

	if (player_hand->same_cnt == 4)
		return FOUR_OF_A_KIND;

	if (player_hand->same_cnt == 3 && player_hand->pairs == 1)
		return FULL_HOUSE;

	if (is_flush)
		return FLUSH;

	if (is_straight)
		return STRAIGHT;

	if (player_hand->same_cnt == 3 && player_hand->pairs == 0)
		return THREE_OF_A_KIND;

	if (player_hand->pairs == 2)
		return TWO_PAIRS;

	if (player_hand->pairs == 1)
		return PAIR;

	return HIGH_CARD;
}

player player_high_card(struct poker_hand *player_hands)
{
	struct poker_hand *white = &player_hands[WHITE];
	struct poker_hand *black = &player_hands[BLACK];

	size_t white_ndx = CARDS_PLAYER - 1;
	unsigned int white_card =
		sym_to_num[(white->cards + (white_ndx-- * SYM_PER_CARD))[VALUE_NDX]];
	player winner = TIE;

	int i;
	for (i = CARDS_PLAYER - 1; i >= 0; --i) {
		unsigned int black_card =
			sym_to_num[(black->cards + (i * SYM_PER_CARD))[VALUE_NDX]];

		if (white_card != black_card) {
			if      (white_card < black_card) winner = BLACK;
			else if (white_card > black_card) winner = WHITE;
			break;
		}
		else {
			white_card =
				sym_to_num[(white->cards + (white_ndx * SYM_PER_CARD))[VALUE_NDX]];
			i = 1 + white_ndx--;
		}
	}

	return winner;
}

unsigned int next_unseen(struct poker_hand *player_hand)
{
	unsigned int next_card = 0;

	int i;
	for (i = CARDS_PLAYER - 1; i >= 0; --i) {
		if ( !player_hand->seen[i]) {
			next_card = sym_to_num[(player_hand->cards + (i * SYM_PER_CARD))[VALUE_NDX]];
			player_hand->seen[i] = true;
			break;
		}
	}

	return next_card;
}

player player_pair(struct poker_hand *player_hands)
{
	struct poker_hand *white = &player_hands[WHITE];
	struct poker_hand *black = &player_hands[BLACK];

	/* get value of pair symbol for the pair */
	unsigned int white_card = sym_to_num[white->pair_values[0]];
	unsigned int black_card = sym_to_num[black->pair_values[0]];

	player winner = TIE;

	if (black_card == white_card) {
		int i;
		for (i = CARDS_PLAYER - 1; i >= 0; --i) {
			black_card = next_unseen(black);
			white_card = next_unseen(white);

			if (white_card != black_card) {
				if      (white_card < black_card) winner = BLACK;
				else if (white_card > black_card) winner = WHITE;
				break;
			}
		}
	}
	else if (black_card > white_card) winner = BLACK;
	else winner = WHITE;

	return winner;
}

player _player_2pairs_2equal(struct poker_hand *white,
							 struct poker_hand *black)
{
	unsigned int black_card = next_unseen(black);
	unsigned int white_card = next_unseen(white);

	if      (white_card < black_card) return BLACK;
	else if (white_card > black_card) return WHITE;
	else 							  return TIE;
}

player _player_2pairs_1equal(struct poker_hand *white,
							 unsigned int white_cards[],
							 struct poker_hand *black,
							 unsigned int black_cards[])
{
	/* get the MAX indices */
	size_t white_ndx = (white_cards[0] > white_cards[1]) ? 0 : 1;
	size_t black_ndx = (black_cards[0] > black_cards[1]) ? 0 : 1;
	player winner = TIE;

	if (white_cards[white_ndx] > black_cards[black_ndx]) {
		winner = WHITE;
	}
	else if (white_cards[white_ndx] < black_cards[black_ndx]) {
		winner = BLACK;
	}
	else if (white_cards[white_ndx] == black_cards[black_ndx]) {
		/* get the other pair (the MIN indices), by flipping MAX */
		white_ndx = (white_ndx + 1) % 2;
		black_ndx = (black_ndx + 1) % 2;
		if (white_cards[white_ndx] == black_cards[black_ndx]) {
			white_cards[0] = next_unseen(black);
			black_cards[0] = next_unseen(white);

			if (white_cards[0] != black_cards[0]) {
				if      (white_cards[0] < black_cards[0]) winner = BLACK;
				else if (white_cards[0] > black_cards[0]) winner = WHITE;
			}
		}
		else if (white_cards[white_ndx] > black_cards[black_ndx])
			winner = WHITE;
		else if (white_cards[white_ndx] < black_cards[black_ndx])
			winner = BLACK;
	}

	return winner;
}

player player_2pairs(struct poker_hand *player_hands)
{
	struct poker_hand *white = &player_hands[WHITE];
	struct poker_hand *black = &player_hands[BLACK];

	/* get value of pair symbol for the pair */
	unsigned int white_cards[] = {
		sym_to_num[white->pair_values[0]],
		sym_to_num[white->pair_values[1]],
	};
	unsigned int black_cards[] = {
		sym_to_num[black->pair_values[0]],
		sym_to_num[black->pair_values[1]],
	};

	player winner = TIE;

	/* both pairs are equal, e.g. KK,QQ and QQ,KK, check the remaining
	 * card for high value */
	if ((white_cards[0] == black_cards[0] && white_cards[1] == black_cards[1])
		|| (white_cards[0] == black_cards[1] && white_cards[1] == black_cards[0])) {
		/* check the remaining card */
		winner = _player_2pairs_2equal(white, black);
	}
	/* one pair is equal and the other differs */
	else if (   (white_cards[0] == black_cards[0] && white_cards[1] != black_cards[1])
			 || (white_cards[0] == black_cards[1] && white_cards[1] != black_cards[0])
			 || (white_cards[1] == black_cards[0] && white_cards[0] != black_cards[1])
			 || (white_cards[1] == black_cards[1] && white_cards[0] != black_cards[0])) {
		winner = _player_2pairs_1equal(white, white_cards, black, black_cards);
	}
	/* both have 2 pairs which are different from each other */
	else {
		size_t white_ndx = (white_cards[0] > white_cards[1]) ? 0 : 1;
		size_t black_ndx = (black_cards[0] > black_cards[1]) ? 0 : 1;

		/* compare the largest pairs from both */
		if      (white_cards[white_ndx] < black_cards[black_ndx]) winner = BLACK;
		else if (white_cards[white_ndx] > black_cards[black_ndx]) winner = WHITE;
	}

	return winner;
}

player player_3kind(struct poker_hand *player_hands)
{
	struct poker_hand *white = &player_hands[WHITE];
	struct poker_hand *black = &player_hands[BLACK];

	unsigned int white_card = sym_to_num[white->same_value];
	unsigned int black_card = sym_to_num[black->same_value];

	if      (white_card < black_card) return BLACK;
	else if (white_card > black_card) return WHITE;
	else {
		do {
			black_card = next_unseen(black);
			white_card = next_unseen(white);
		} while (black_card == white_card && (black_card != 0 || white_card != 0));

		if      (white_card < black_card) return BLACK;
		else if (white_card > black_card) return WHITE;

		return TIE;
	}
}

player player_straight(struct poker_hand *player_hands)
{
	struct poker_hand *white = &player_hands[WHITE];
	struct poker_hand *black = &player_hands[BLACK];

	unsigned int white_card = sym_to_num[
		(white->cards + (CARDS_PLAYER - 1) * SYM_PER_CARD)[VALUE_NDX]];
	unsigned int black_card = sym_to_num[
		(black->cards + (CARDS_PLAYER - 1) * SYM_PER_CARD)[VALUE_NDX]];

	if      (white_card < black_card) return BLACK;
	else if (white_card > black_card) return WHITE;
	else 							  return TIE;
}

player player_flush(struct poker_hand *player_hands)
{
	return player_high_card(player_hands);
}

player player_full_house(struct poker_hand *player_hands)
{
	struct poker_hand *white = &player_hands[WHITE];
	struct poker_hand *black = &player_hands[BLACK];

	player winner = player_3kind(player_hands);
	if (winner == TIE) {
		/* check for pair ranks if 3ees match */
		unsigned int white_card = (white->pairs == 1) ?
			sym_to_num[white->pair_values[0]] : 0;
		unsigned int black_card = (black->pairs == 1) ?
			sym_to_num[black->pair_values[0]] : 0;

		if      (white_card < black_card) winner = BLACK;
		else if (white_card > black_card) winner = WHITE;
	}
	return winner;
}

player player_4kind(struct poker_hand *player_hands)
{
	return player_3kind(player_hands);
}

player player_straight_flush(struct poker_hand *player_hands)
{
	return player_straight(player_hands);
}

void find_winner(struct poker_hand *player_hands)
{
	hand black_hand = player_hand_rank(&player_hands[BLACK]);
	hand white_hand = player_hand_rank(&player_hands[WHITE]);

	player winner = TIE;
	if (black_hand > white_hand)
		winner = BLACK;
	else if (black_hand < white_hand)
		winner = WHITE;
	else { /* black_hand == white_hand */
		if (black_hand == STRAIGHT_FLUSH)
			winner = player_straight_flush(player_hands);
		else if (black_hand == FOUR_OF_A_KIND)
			winner = player_4kind(player_hands);
		else if (black_hand == FULL_HOUSE)
			winner = player_full_house(player_hands);
		else if (black_hand == FLUSH)
			winner = player_flush(player_hands);
		else if (black_hand == STRAIGHT)
			winner = player_straight(player_hands);
		else if (black_hand == THREE_OF_A_KIND)
			winner = player_3kind(player_hands);
		else if (black_hand == TWO_PAIRS)
			winner = player_2pairs(player_hands);
		else if	(black_hand == PAIR)
			winner = player_pair(player_hands);
		else if (black_hand == HIGH_CARD)
			winner = player_high_card(player_hands);
	}

	if      (winner == BLACK) printf("Black wins.\n");
	else if (winner == WHITE) printf("White wins.\n");
	else if (winner == TIE)   printf("Tie.\n");
}

int main(int argc, const char **argv)
{
	(void)argc;
	(void)argv;
	int status;
	size_t i, j;

	struct poker_hand player_hands[PLAYER_COUNT];

	while ( !feof(stdin)) {
		memset(player_hands, 0, sizeof(player_hands));
		for (i = 0; i < PLAYER_COUNT; ++i) {
			for (j = 0; j < CARDS_PLAYER; ++j) {
				status = scanf(" %2s", player_hands[i].cards + (j * SYM_PER_CARD));
			}
		}
		status = scanf("\n");
		find_winner(player_hands);
	}

	exit(EXIT_SUCCESS);
}
Wher's the problem, why I can't get AC?

Thanks
Post Reply

Return to “Volume 103 (10300-10399)”