Poker Solitaire Evaluator

Input

The input will contain several test cases. First line of the input is the an integer which indicate the number of test case followed by a blank line. Each consecutive test case will also separated by a blank line.

Each test case gets 25 cards, 5 cards per line. Each card consists of two characters. The first represents the rank of the card: `A’, `2′, `3′, `4′, `5′, `6′, `7′, `8′, `9′, `X’, `J’, `Q’, `K’. The second represents the suit of the card: `S’, `H’, `D’, `C’.

tex2html_wrap_inline44

The cards are dealt into a  square. Each row and column is evaluated to determine the highest hand type for which its 5 cards qualify. The hand types, from low to high, are Nothing, Pair, Two Pair, Three of a Kind, Straight, Flush, Full House, Four of a Kind, Straight Flush. A hand qualifies only once, and then only for its highest type. For example, a Four of a Kind does not count as two pair or three of a kind.

Output

For each test case output a list of 9 integers, telling how many hands of each handtype were found. from lowest to highest, being:

  1. Nothing: does not qualify as any of the following. Example: AC, 3H, QS, JD, 7D.
  2. One Pair: contains two cards of the same rank and does not qualify for any of the following. Example: 2C, 3H, 4H, 2H, KD.
  3. Two Pair: contains two cards of one rank and two cards of another and does not qualify for any of the following. Example: 2C, 3H, 4H, 2H, 4D.
  4. Three of a Kind: contains three cards of the same rank and does not qualify for any of the following. Example: QS, KH, 2C, QD, QC.
  5. Straight: the five cards of the hand may be sorted on rank so that an unbroken sequence of 5 ranks is formed and the hand does not qualify for any of the following. There can be cycle through Ace. That is AC, 2H, 4D, 3H, 5S forms a straight, as does JH, XD,QC, KD, AS and QC, KD, AS, 2H, 3D.
  6. Flush: the five cards are all of the same suit and the hand does not qualify for any of the following. Example: 5D, AD, KD, 7D, QD.
  7. Full House: the hand contains three cards of one rank and two cards of another. Example: 3C, QS, QD, 3H, 3S.
  8. Four of a kind: the hand contains four cards of the same rank. Example: AS, AD, AH, 7C, AC.
  9. Straight Flush: the hand meets the criteria for being both a straight and a flush.

Two consecutive output will separated by a blank line.

For the example below, the five rows evaluate to Straight Flush, Straight, Pair, Flush, Three of a Kind. The Five columns evaluate to Four of A Kind, Full House, Two Pair, Nothing, and Two Pair.

Sample Input

1 
AS 2S 3S 4S 5S
AC 2H 3H 5C 4C
AH 2D KC KH 5D
AD 3D KD 9D 8D
XH 3C XC XS 8C

Sample Output

1, 1, 2, 1, 1, 1, 1, 1, 1

C Code

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

char table[6][6][3];
char ss[6][3];
int rank[300], A[6];

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

void Ini() {
	char tt[] = "A23456789XJQK";
	int i, j;
	for(i = 0; tt[i]; i++) {
		j = tt[i];
		rank[j] = i;
	}
}



int Fourofkind() {
	int i, k, j;
	int a[10] = {0};
	for(i = 0; i<5; i++) {
		if(a[i]) continue;
		k = 1;
		for(j = i+1; j<5; j++) {
			if(ss[i][0] == ss[j][0]){
				k++;
				a[j] = 1;
			}

		}
		if(k == 4) return 1;
	}
	return 0;
}

int Fullhouse() {

	int a[10] = {0};
	int b[10] = {0};
	int i, j, c ;
	for(i  = 0; i<5; i++) {
		if(a[i]) continue;
		c = 1;
		for(j = i+1; j<5; j++) {
			if(ss[i][0] == ss[j][0]) {
				c++;
				a[j] = 1;
			}
		}
		b[c] ++; 
	}
	if(b[3] == 1 && b[2] == 1) return 1;
	return 0;
}

int Flush() {
	int i;
	for(i = 1; i<5; i++) 
		if(ss[i][1] != ss[i-1][1]) return 0;
	return 1;
}

int Straight() {
	int i, j, d = 1, c, k;
	int f[15] = {0};
	for(i = 0; i<5; i++) {
		j = ss[i][0];
		c = rank[j];
		f[c] = 1;
		k = c;
	}
	c = k+1;
	c %= 13;
	while(f[c]) {
		d++;
		c++;
		c %= 13;
	}
	c = k-1 + 13;
	c %= 13;
	while(f[c]) {
		d++;
		c--;
		c = (c+13)%13;
	}
	if(d == 5) return 1;
	return 0;
}

int Threeofakind() {
	int a[6] = {0};
	int i, c ;
	for(i = 0; i<5; i++) {
		if(a[i]) continue;
		c = 1;
		for(int j = i+1; j<5; j++) {
			if(ss[i][0] == ss[j][0]){
				c++;
				a[j] = 1;
			}
		}
		if(c == 3) return 1;
	}

	return 0;
}

int Twopair() {

	int a[7] = {0};
	int b[7] = {0};
	int i, j, c ;
	for(i  = 0; i<5; i++) {
		if(a[i]) continue;
		c = 1;
		for(j = i+1; j<5; j++) {
			if(ss[i][0] == ss[j][0]) {
				c++;
				a[j] = 1;
			}
		}
		b[c] ++; 
	}
	if(b[2] == 2) return 1;
	return 0;
}

int Onepair() {
	int a[6] = {0};
	int i, c ;
	for(i = 0; i<5; i++) {
		if(a[i]) continue;
		c = 1;
		for(int j = i+1; j<5; j++) {
			if(ss[i][0] == ss[j][0]){
				c++;
				a[j] = 1;
			}
		}
		if(c == 2) return 1;
	}

	return 0;
}


int Decide() {
	int f, s;
	if(Fourofkind()) return 8;
	if(Fullhouse())  return 7;
	f = Flush();
	s = Straight();
	if(s && f) return 9;
	if(f) return 6;
	if(s) return 5;
	if(Threeofakind()) return 4;
	if(Twopair()) return 3;
	if(Onepair()) return 2;
	return 1;
}

void Cal() {
	int a[10] = {0};
	int i, j, d;
	for( i = 0; i<5; i++) {
		for(j = 0; j<5; j++)
			strcpy(ss[j],table[i][j]);
		d = Decide();
		a[d]++;
	}
	for(i = 0; i<5; i++) {
		for(j = 0; j<5; j++)
			strcpy(ss[j],table[j][i]);
		d = Decide();
		a[d]++;
	}
	printf("%d",a[1]);
	for(i = 2; i<=9; i++)
		printf(", %d",a[i]);
	printf("\n");
}

void ReadCase() {
	int i, j, k = 0;
	char input[100];
	while(gets(input)) {
		for(i = 0; input[i]; i++) 
			if(input[i] == '\n')
				input[i] = NULL;
		if(strlen(input) == 0 ) break;
		sscanf(input,"%s%s%s%s%s",table[k][0],table[k][1],
				table[k][2],table[k][3],table[k][4]);
		k++;
		if(k % 5 ==0)
			Cal();
	}
}
void main() {
	int kase;
	char in[100];
	///freopen("c:\\h.txt","r",stdin);
	gets(in);
	sscanf(in,"%d",&kase);
	gets(in);
	Ini();
	//scanf("%d",&kase);
	while(kase--) {
		ReadCase();
	//	Cal();
		if(kase) printf("\n");
	}
}