help me out guys
i've checked all samples but still wrong answer from the judge
10315 - Poker Hands
Moderator: Board moderators
-
- Guru
- Posts: 5947
- Joined: Thu Sep 01, 2011 9:09 am
- Location: San Jose, CA, USA
Re: 10315 - Poker Hands
Try input:
3D 3H 4D 4H 2S 5C 5S AH KD QC
Output should be
Black wins.
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!
Re: 10315 - Poker Hands
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.
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.
Re: 10315 - Poker Hands
Here is the code.
Wher's the problem, why I can't get AC?
Thanks
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);
}
Thanks