Notice
Recent Posts
Recent Comments
Link
«   2024/09   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30
Archives
Today
Total
관리 메뉴

Life Engineering

[SWEA 9760] Poker Game (Java) 본문

Problem Solving

[SWEA 9760] Poker Game (Java)

흑개 2022. 4. 12. 14:28

https://swexpertacademy.com/main/code/userProblem/userProblemDetail.do?contestProbId=AXEN3aEKDrsDFAVX 

 

SW Expert Academy

SW 프로그래밍 역량 강화에 도움이 되는 다양한 학습 컨텐츠를 확인하세요!

swexpertacademy.com

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.Collections;
import java.util.StringTokenizer;

public class Solution_SWEA_9760 {
	static class Card{
		char suit, rank;
		Card(char suit, char rank){
			this.suit=suit;
			this.rank=rank;
		}
	}
	static int T;
	static char[] ranks= {'A', '2', '3', '4', '5', '6', '7', '8', '9', 'T', 'J', 'Q', 'K'};
	static StringBuilder sb;
	public static void main(String[] args) throws NumberFormatException, IOException {
		BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st=null;
		T=Integer.parseInt(br.readLine());
		for (int t=1; t<=T; t++) {
			Card[] cards=new Card[5];
			st=new StringTokenizer(br.readLine());
			sb=new StringBuilder();
			for (int i=0; i<5; i++) {
				String c=st.nextToken();
				cards[i]=new Card(c.charAt(0), c.charAt(1));
			}
			if (isSameSuit(cards)) {	//1, 4
				if (isSerial(cards)) {	//1
					sb.append("Straight Flush");
				}
				else {		//4
					sb.append("Flush");
				}
			}
			else {		//2, 3, 5, 6, 7, 8
				if (isSerial(cards)) {	//5
					sb.append("Straight");
				}
				else {
					rankCheck(cards);
				}
				//2, 3, 6, 7, 8
			}
			System.out.println("#"+t+" "+sb.toString());
		}

	}
	private static boolean isSameSuit(Card[] cards) {
		char suit=cards[0].suit;
		for (int i=1; i<cards.length; i++) {
			if (suit!=cards[i].suit) return false;
		}
		return true;
	}
	
	private static boolean isSerial(Card[] cards) {
		Integer[] cntArr=new Integer[ranks.length];
		for (int i=0; i<ranks.length; i++) {
			cntArr[i]=new Integer(0);
		}
		for (int i=0; i<cards.length; i++) {
			int idx=findIndex(cards[i].rank);
			cntArr[idx]+=1;
			if (cntArr[idx]>1) return false;
		}
		if (cntArr[0]==1 && cntArr[9]==1 && cntArr[10]==1 && cntArr[11]==1 && cntArr[12]==1) return true; 
		for (int i=0; i<cntArr.length; i++) {
			if (cntArr[i]==1) {
				if (i<10) {
					for (int cnt=0; cnt<5; cnt++) {
						if (cntArr[(i+cnt)%ranks.length]!=1) return false;
					}
					return true;
				}
				else {
					return false;
				}
			}
		}
		return false;
	}

	private static void rankCheck(Card[] cards) {	//2, 3, 6, 7, 8
		Integer[] cntArr=new Integer[ranks.length];
		for (int i=0; i<ranks.length; i++) {
			cntArr[i]=new Integer(0);
		}
		for (int i=0; i<cards.length; i++) {
			cntArr[findIndex(cards[i].rank)]+=1;
		}
		Arrays.sort(cntArr, Collections.reverseOrder());
		int zero=cntArr[0], one=cntArr[1], two=cntArr[2], three=cntArr[3];
		if (zero==4 && one==1) sb.append("Four of a Kind");
		else if (zero==3 && one==2) sb.append("Full House");
		else if (zero==3 && one==1 && two==1) sb.append("Three of a kind");
		else if (zero==2 && one==2 && two==1) sb.append("Two pair");
		else if (zero==2 && one==1 && two==1 && three==1) sb.append("One pair");
		else sb.append("High card");
	}
	private static int findIndex(char rank) {
		for (int i=0; i<ranks.length; i++) {
			if (rank==ranks[i]) return i;
		}
		return -1;
	}
}

조금 복잡하게 풀었다..

카드의 슈트와 랭크값을 받아서 객체에 저장 후,

1) 같은 슈트인지 체크한다 => isSameSuit 함수 (첫번째 슈트와 그 나머지 슈트가 동일할 경우)

2) 연속인지 체크한다 => isSerial 함수 (랭크값과 cntArr 인덱스를 연관지어 1씩 증가시켜준다, cntArr 값 중 1이 있으면 그 이후부터 5개 탐색하여 같은 1이 있는지 체크한다)

3) 이후 2,3,6,7,8 케이스인지 체크한다 => rankCheck 함수 (마찬가지로 랭크값과 cntArr 인덱스를 연관지어 1씩 증가시켜주고, 내림차순으로 정렬하여 cntArr 배열의 0,1,2,3 번째 값을 저장한 후 case에 맞게 답을 출력한다)

 

다른 분(https://imnotabear.tistory.com/97)

코드를 보니, 더 간단하게 풀 수 있었다

 

suit, rank 배열을 따로 만들어준다. 들어오는 카드에 따라 해당하는 suit, rank를 각 배열에 ++ 시켜준다.

이후 suit 배열을 순회하여 5개가 나오면 flush 플래그를 true로 전환한다.

 

이후 연속되는 것을 체크하고, rank들을 체크하기 위해 rank배열을 순회하면서 각 플래그 값(continue(연속되는지)), four, three, two 와 같은 값들을 표시해주면 된다. 각 rank가 3이면 three=true, 2면 two++ 해주는 식으로 각 case 를 구분할 수 있도록 변수를 써주면 된다..