출처 : programming-challenges.com
알고리즘은 쉽지만 어떻게 디자인을 할 지에 대해서 고민해 볼 수 있는 좋은 문제.
포커용 카드는 52개의 카드로 이루어진다. 각 카드는 클럽, 다이아몬드, 하트, 스페이드(입력 데이터에서는 각각 C,D,H,S로 표시)중 한 가지 무늬를 가진다. 또한 각 카드는 2에서 10까지, 그리고 잭, 퀸, 킹, 또는 에이스(2,3,4,5,6,7,8,9,T,J,Q,K,A로 표기)의 값을 갖는다. 점수를 매길 때 위에 열거한 순서대로 등급이 매겨지며 2가 가장 낮고 에이스가 가장 높다. 무늬는 값에 영향을 끼치지 않는다.
포커 패는 다섯 장의 카드로 구성되며 다음과 같은 순서로 등급이 매겨진다.
몇 쌍의 포커 패를 비교해서 어느 쪽이 이겼는지 아니면 무승부인지 알아내자.
Input
입력 파일은 여러 줄로 구성되며 각 줄에는 열 장의 카드를 나타내는 값이 들어간다. 앞에 있는 다섯 장의 카드는 "Black"이라는 참가자의 카드고 뒤에 있는 다섯장의 카드는 "White"라는 참가자의 카드다.
output
입력된 각 줄에 대해 다음 중 한 가지가 들어있는 행을 출력한다.(첫번째는 Black이 이기는 경우, 두 번째는 White가 이기는 경우, 세번째는 둘이 비기는 경우)
Black wins.
White wins.
Tie.
Sample Input
2H 3D 5S 9C KD 2C 3H 4S 8C AH
2H 4S 4C 2D 4H 2S 8S AS QS 3S
2H 3D 5S 9C KD 2C 3H 4S 8C KH
2H 3D 5S 9C KD 2D 3H 5C 9S KH
Sample Output
White wins.
Black wins.
Black wins.
Tie.
Test Case
다음 URL의 파일을 다운로드 후 체크하면 Black이 376번 승리
16개의 풀이가 있습니다.
파이썬으로 작성해봤습니다. 라이브러리들을 잘 몰라서 좀 길어지는것같네요..
import os
import sys
import re
#
# Kind of Cards and Order of Values
#
kind = ['S', 'C', 'D', 'H']
order = ['2', '3', '4', '5', '6', '7',
'8', '9', 'T', 'J', 'Q', 'K', 'A']
#
# Ordering Algorithm
#
def ordering(list, order):
return [x for x in order for y in list if y == x]
#
# Checking Consecutive Number Algorithm
#
def isConsec(list):
ordered = ordering(list, order)
count = len(list)
for i in range(0, 13):
if ordered == ordering((order + order)[i:i+count], order):
# Return True and Value of highest card
return [True, ordered[-1]]
return [False]
#
# Gamer Class
#
class Gamer():
card = []
grade = 0
highest = ''
def __init__(self, name):
self.name = name
#
# Check Royal Straight Flush (Grade 10)
# Return True or False
#
def ro_str_flu(self):
for kin in kind:
if self.card[1].count(kin) == 5:
place = [i for i, x in enumerate(self.card[1]) if x == kin]
get_val = [ self.card[0][x] for x in place ]
if ordering(get_val, order) == ['T', 'J', 'Q', 'K', 'A']:
self.grade = 10
self.highest = 'A'
return True
return False
#
# Check Straight Flush (Grade 9)
# Return True or False
#
def str_flu(self):
for kin in kind:
if self.card[1].count(kin) == 5:
place = [i for i, x in enumerate(self.card[1]) if x == kin]
get_val = [ self.card[0][x] for x in place ]
result = isConsec(get_val)
if result[0]:
self.grade = 9
self.highest = result[1]
return True
return False
#
# Check Four Cards (Grade 8)
# Return True or False
#
def four_cards(self):
for x in order:
if self.card[0].count(x) == 4:
self.grade = 8
self.highest = x
return True
return False
#
# Check Full House (Grade 7)
# Return True or False
#
def full_house(self):
for x in order:
if self.card[0].count(x) == 3:
for y in order:
if y != x and self.card[0].count(y) == 2:
self.grade = 7
self.highest = x
return True
return False
#
# Check Flush (Grade 6)
# Return True or False
#
def flush(self):
for x in kind:
if self.card[1].count(x) == 5:
self.grade = 6
self.highest = ordering(self.card[0], order)
return True
return False
#
# Check Straight (Grade 5)
# Return True or False
#
def straight(self):
result = isConsec(self.card[0])
if result[0] == True:
self.grade = 5
self.highest = ordering(self.card[0], order)
return True
return False
#
# Check Triple (Grade 4)
# Return True or False
#
def triple(self):
for x in order:
if self.card[0].count(x) == 3:
self.grade = 4
self.highest = x
return True
return False
#
# Check Two Pairs (Grade 3)
# Return True or False
#
def two_pair(self):
for x in order:
if self.card[0].count(x) == 2:
for y in order:
if self.card[0].count(y) == 2 and y != x:
self.grade = 3
self.highest = ordering([x,y], order)
return True
return False
#
# Check One Pair (Grade 2)
# Return True or False
#
def one_pair(self):
for x in order:
if self.card[0].count(x) == 2:
self.grade = 2
self.highest = x
return True
return False
#
# Check High Card (Grade 1)
# Return name who have higher card
#
def high_card(self):
self.grade = 1
self.highest = ordering(self.card[0],order)
return True
functions = [ ro_str_flu, str_flu, four_cards,
full_house, flush, straight,
triple, two_pair, one_pair, high_card ]
Grade = [ '', 'High Card', 'Pair', 'Two Pair', 'Triple', 'Straight', 'Flush',
'Full House', 'Four of a Kind', 'Straight Flush', 'Royal Straight Flush']
#
# Check out what Gamer has
#
def what_has(self):
for function in self.functions:
result = function(self)
if result == True:
return
#
# Compare with Pop
#
def compare_pop(list1, list2):
while True:
try :
temp_1 = list1.pop()
temp_2 = list2.pop()
except IndexError : return -1
if order.index(temp_1) > order.index(temp_2):
return 0
elif order.index(temp_1) < order.index(temp_2):
return 1
#
# ------------------------------------------
# Read Files
#
path = os.path.dirname(os.path.abspath(__file__))
try : f = open( path + '/' + "card games.txt", 'r')
except IOError : print("'card games.txt' does not exist"); sys.exit()
temp = f.readlines()
f.close()
num_games = len(temp)
if temp[num_games - 1] == "\n":
del temp[num_games - 1]
num_games = len(temp)
#
# Iterate games
#
for game in range(0, num_games):
black = Gamer("Black")
white = Gamer("White")
card_b = temp[game].split()[:5]
card_w = temp[game].split()[5:]
black.card = [ [ x[0] for x in card_b ], [ x[1] for x in card_b ]]
white.card = [ [ x[0] for x in card_w ], [ x[1] for x in card_w ]]
black.what_has()
white.what_has()
#
# Compare Black's and White's results
#
if black.grade > white.grade:
print(black.name + " is win as " + black.Grade[black.grade])
elif black.grade < white.grade:
print(white.name + " is win as " + white.Grade[white.grade])
else :
if len(black.highest) == 1:
if order.index(black.highest) > order.index(white.highest):
print(black.name + " is win as " + black.Grade[black.grade]
+ ', ' + black.highest)
elif order.index(black.highest) < order.index(white.highest):
print(white.name + " is win as " + white.Grade[black.grade]
+ ', ' + white.highest)
else :
print("Tie")
else :
result = compare_pop(black.highest, white.highest)
if result == 0:
print(black.name + " is win as " + black.Grade[black.grade])
elif result == 1:
print(white.name + " is win as " + white.Grade[white.grade])
else :
print("Tie")
실제 포커룰하고는 약간 다르죠. 문제에서 주어진 룰에서는 A,2,3,4,5 스트레이트는 없어요.포커친지가 하두 오래되서.. 이게 백스트레이트였나요? 그리고 실제룰에서는 무늬도 상하등급이 있는데 말이죠. 파이썬은 리스트나 튜플의 크기비교를 할때, 금은동 메달 비교하듯이 비교해줘서, 이럴때 정말 유용하네요.
def rank(cards):
d={'T':10,'J':11,'Q':12,'K':13,'A':14}
for i in range(1,10) : d[str(i)]=i
shapes = [x[1] for x in cards]
nums = [d.get(x[0]) for x in cards]
nums.sort(reverse=True)
straight=flush=False
if len(set(shapes))==1 : flush=True
if len(set(nums))==5 and nums[0]-nums[4]==4 : straight=True
if straight & flush : return [8]+nums #straight flush
if flush : return [5]+nums #flush
if straight : return [4]+nums #straight
if len(set(nums))==2:
for c in set(nums):
if nums.count(c)==4: return [7,c] # four cards
if nums.count(c)==3: return [6,c] # full house
if len(set(nums))==3:
for c in set(nums):
if nums.count(c)==3: return [3,c] # triple
if nums.count(c)==2:
for x in set(nums):
if nums.count(x)==1:
nums.remove(x)
return [2]+nums+[x] # two pairs
for c in nums:
if nums.count(c)==2:
nums.remove(c)
return [1,c]+nums # one pair
return [0]+nums # high card
count=0
for line in file('s423.txt'): # http://euler.synap.co.kr/files/poker.txt
cc = line.split()
count += rank(cc[:5])>rank(cc[5:])
print count
생각보다 재밌네요.
스트레이트 체크하는거랑 패가 같을 경우에 높은 수 체크하는 부분이 좀 까다로웠습니다. 파이썬 itertools의 combination 함수를 몰랐으면 무척 애 먹었을 것 같네요.
oop 스타일로 만들어 봤습니다.
파이썬입니다.
import unittest
import itertools
ORDER = ['2','3','4','5','6','7','8','9','T','J','Q','K','A']
#
# compare two card sets
#
def _compare(b_cards, w_cards):
r1 = reversed(sorted([ORDER.index(c.num) for c in b_cards]))
r2 = reversed(sorted([ORDER.index(c.num) for c in w_cards]))
for b, w in zip(r1, r2):
if b > w: return 1
elif b < w: return -1
return 0
class Card:
def __init__(self, s):
self.num = s[0]
self.pat = s[1]
class PokerHand:
def __init__(self, s):
self.cards = set([Card(c) for c in s.split()])
self.made = []
made_cards = [
StraightFlush(),
FourCard(),
FullHouse(),
Flush(),
Straight(),
ThreeCard(),
TwoPair(),
OnePair(),
HighCard(),
]
for made in made_cards:
made.check_made(self.cards)
if made.isMade():
self.made.append(made)
def getTopMade(self):
levels = map(lambda m:m.level, self.made)
return self.made[levels.index(max(levels))]
def getHighCard(self):
levels = map(lambda m:m.level, self.made)
return self.made[levels.index(1)]
def win(self, other):
#
# compare top-made card level
#
b_made = self.getTopMade()
w_made = other.getTopMade()
if b_made.level > w_made.level: return True
elif b_made.level < w_made.level: return False
#
# if top-made level is same,
# compare which card is higher in made
#
c = self.getTopMade().compare(other.getTopMade())
if c == 1: return True
elif c==-1: return False
#
# if all is same, compare high card
#
c = self.getHighCard().compare(other.getHighCard())
if c == 1: return True
else: return False # Tie!!
class Made:
def __init__(self):
self.name = self.__class__.__name__
self.cards_sets = []
def made(self, *cards):
for card in cards:
self.cards_sets.append(card)
def isMade(self):
return self.cards_sets
def isSameNum(self, cards):
num = cards[0].num
for c in cards[1:]:
if c.num != num: return False
num = c.num
return True
def compare(self, other):
for b_cards, w_cards in zip(self.cards_sets, other.cards_sets):
c = _compare(b_cards, w_cards)
if c in [1, -1]: return c
return 0
#
# Made Cards (StraightFlush, FourCard, FullHouse, ...)
#
class StraightFlush(Made):
level = 9
def check_made(self, cards):
straight = Straight()
straight.check_made(cards)
flush = Flush()
flush.check_made(cards)
if straight.isMade() and flush.isMade():
self.made(cards)
class FourCard(Made):
level = 8
def check_made(self, cards):
for cList in itertools.combinations(cards, 4):
if self.isSameNum(cList):
self.made(cList)
class FullHouse(Made):
level = 7
def check_made(self, cards):
for cList in itertools.combinations(cards, 3):
remains = list(cards - set(cList))
if self.isSameNum(cList) and self.isSameNum(remains):
self.made(cList, remains)
class Flush(Made):
level = 6
def check_made(self, cards):
cardList = list(cards)
pat = cardList[0].pat
for c in cardList[1:]:
if c.pat != pat: return
pat = c.pat
self.made(cardList)
class Straight(Made):
level = 5
def check_made(self, cards):
minIndex, maxIndex = 99, -1
for c in cards:
idx = ORDER.index(c.num)
if idx < minIndex: minIndex = idx
if idx > maxIndex: maxIndex = idx
sorted_num = sorted(map(lambda c:c.num, cards))
if sorted_num == ['2','3','4','5','A']:
self.made(cards)
elif len(set(sorted_num))==5 and maxIndex-minIndex==4:
self.made(cards)
class ThreeCard(Made):
level = 4
def check_made(self, cards):
for cList in itertools.combinations(cards, 3):
if self.isSameNum(cList):
self.made(cList)
class TwoPair(Made):
level = 3
def check_made(self, cards):
for cList in itertools.combinations(cards, 2):
if self.isSameNum(cList):
for cList2 in itertools.combinations(cards-set(cList), 2):
if self.isSameNum(cList2):
#
# higher first
#
if _compare(cList, cList2) == 1:
self.made(cList, cList2)
else:
self.made(cList2, cList)
class OnePair(Made):
level = 2
def check_made(self, cards):
for cList in itertools.combinations(cards, 2):
if self.isSameNum(cList):
self.made(cList)
class HighCard(Made):
level = 1
def check_made(self, cards):
self.made(cards)
#
# Quiz line : in/out
#
def checkWinner(line):
cards = line.split()
black = PokerHand(" ".join(cards[:5]))
white = PokerHand(" ".join(cards[5:]))
if black.win(white):return "Black wins."
elif white.win(black):return "White wins."
else: return "Tie."
#
# Test Code
#
class MyTest(unittest.TestCase):
def testCard(self):
c1 = Card("2H")
self.assertEquals("2", c1.num)
self.assertEquals("H", c1.pat)
def testMade(self):
fourCard = PokerHand("2H 2D 2S 2C 3D")
flush = PokerHand("AH 2H 3H 4H 7H")
straight = PokerHand("6H 2H 3H 4H 5D")
straightFlush = PokerHand("6H 2H 3H 4H 5H")
fullHouse = PokerHand("6H 6D 6S 4C 4H")
threeCard = PokerHand("6H 6D 6S 4C 5H")
twoPair = PokerHand("6H 6D 5S 4C 5H")
onePair = PokerHand("6H 6D 8S 7C 5H")
highCard = PokerHand("6H 7D 8S 9C JH")
self.assertEquals(8, fourCard.getTopMade().level)
self.assertEquals("FourCard", fourCard.getTopMade().name)
self.assertEquals("Flush", flush.getTopMade().name)
self.assertEquals("Straight", straight.getTopMade().name)
self.assertEquals("StraightFlush", straightFlush.getTopMade().name)
self.assertEquals("FullHouse", fullHouse.getTopMade().name)
self.assertEquals("ThreeCard", threeCard.getTopMade().name)
self.assertEquals("TwoPair", twoPair.getTopMade().name)
self.assertEquals("OnePair", onePair.getTopMade().name)
self.assertEquals(2, onePair.getTopMade().level)
self.assertEquals("HighCard", highCard.getTopMade().name)
self.assertTrue(fourCard.win(flush))
self.assertTrue(straightFlush.win(fourCard))
self.assertTrue(straightFlush.win(onePair))
def testSamePokerHand(self):
b = PokerHand("2H 2D 2S 2C AH")
w = PokerHand("3H 3D 3S 3C TH")
self.assertFalse(b.win(w))
self.assertTrue(w.win(b))
def testSameStraightFlush(self):
b = PokerHand("6H 2H 3H 4H 5H")
w = PokerHand("AH 2H 3H 4H 5H")
self.assertTrue(w.win(b))
def testSameFullHouse(self):
b = PokerHand("6H 6D 6S 4C 4H")
w = PokerHand("6H 6D 6S 5C 5H")
self.assertTrue(w.win(b))
b = PokerHand("2H 2D 2S AC AH")
w = PokerHand("6H 6D 6S 5C 5H")
self.assertTrue(w.win(b))
def testSameFlush(self):
b = PokerHand("AH 2H 3H 4H 5H")
w = PokerHand("6H 2H 3H 4H 5H")
self.assertTrue(b.win(w))
def testSameStraight(self):
b = PokerHand("6H 2H 3H 4H 5D")
w = PokerHand("AH 2H 3H 4H 5D")
self.assertTrue(w.win(b))
def testSameThreeCard(self):
b = PokerHand("6H 6D 6S 4C 5H")
w = PokerHand("3H 3D 3S 4C 5H")
self.assertTrue(b.win(w))
b = PokerHand("6H 6D 6S 4C 5H")
w = PokerHand("6H 6D 6S AC 5H")
self.assertTrue(w.win(b))
b = PokerHand("2H 2D 2S AC 5H")
w = PokerHand("6H 6D 6S 3C 5H")
self.assertTrue(w.win(b))
def testSameTwoPair(self):
b = PokerHand("6H 6D 5S 5C 8H")
w = PokerHand("6H 6D 5S 5C 7H")
self.assertTrue(b.win(w))
b = PokerHand("7H 7D 5S 5C 7H")
w = PokerHand("6H 6D 5S 5C 7H")
self.assertTrue(b.win(w))
b = PokerHand("6H 6D 5S 5C 7H")
w = PokerHand("6H 6D 4S 4C 7H")
self.assertTrue(b.win(w))
def testSameOnePair(self):
b = PokerHand("6H 6D 2S 3C AH")
w = PokerHand("6H 6D 2S 3C 4H")
self.assertTrue(b.win(w))
b = PokerHand("8H 8D 2S 3C 4H")
w = PokerHand("6H 6D 2S 3C 4H")
self.assertTrue(b.win(w))
def testCheckWinner(self):
print checkWinner("2H 3D 5S 9C KD 2C 3H 4S 8C AH")
print checkWinner("2H 4S 4C 2D 4H 2S 8S AS QS 3S")
print checkWinner("2H 3D 5S 9C KD 2C 3H 4S 8C KH")
print checkWinner("2H 3D 5S 9C KD 2D 3H 5C 9S KH")
if __name__ == "__main__":
unittest.main()
JAVA입니다
알고리즘:
<input_to_value 함수>
* 한 패(hand) 값 → value[line][hand][5]
한 패의 모양(suit)은 flush[][](5장 모두 같은지) 여부만 체크
* 입력받은 value[][][5]를 작은 순서대로 재배열함 (ORDERING)
<typef 함수>
# comp[][] : 두 패(hand)모두 한 type일 경우, 승패를 위해 비교할 값
→ High Card, Straight, Flush, Straight Flush) 가장 큰 값 ⇒ comp[l][hand]=value[l][hand][4];
→ 같은 값의 쌍이 있는 type들) 같은 쌍을 이루는 값 (2Pairs: 큰 값의 쌍, Fullhouse: 3개 같은 값)
# comp2[][] : 두 패 모두 2Pairs이고, 게다가 두 패의 comp까지 같을 경우,
값이 aabbc, aabcc (a<b<c) 등인 경우에는 comp를 제외하고 가장 큰 값(b,c)이 아닌,
더 작지만 또다른 쌍을 이루는 값 a를 비교해야 한다 → comp2[][]=a
(두 패 모두 2Pairs일 경우에만 사용하는 변수)
* diff[line][hand][4]사용 : value 순서대로 앞숫자와 뒷숫자의 차이
diff[][][j]=value[][][j+1]-value[][][j+1];
* diff[][][]==0 앞뒤 값(value)이 같다는 뜻
diff[][][]==1 앞뒤 값(value)이 연속이라는 뜻
* count0: 한 패(hand)의 diff에서 0의 갯수 (앞뒤 한 쌍의 값이 같은 경우)
con0: 한 패의 diff에서 연속으로 0이 있는 경우의 수 (value가 연속으로 같은 값을 가짐)
* count1: 한 패(hand)의 diff에서 1의 갯수
→ (count1==4) : Straight (값 5개가 모두 연속)
(?: 0이 아닌 수)
* count0==1) 한 쌍의 value가 같음 ⇒ One Pair(type=1)
* count0==2) diff[][][4]=00??, ?00?, ??00 (con0==1) ⇒ 3개 value 같음: 3 of a Kind(type=3)
diff[][][4]=0?0?, ?0?0, 0??0 (con0==0) ⇒ 같은 value가 두 쌍: 2 Pairs(type=2)
※ 0?0?일 경우 값은 aabbc (a<b<c)인데, 나중에 두 패 모두 2 Pairs일 경우 비교값(comp)는 가장 큰 값 c가 아닌,
쌍을 이루는 값 b다. 만약 comp(b)까지 같을 경우, c가 아닌 또 다른 쌍의 값 a를 다른 패와 비교해야 하므로,
이를 위해 comp2=a 설정.
0??0 aabcc인 경우도 마찬가지 comp2=a
comp2[][]=(diff[][][0]==0)?value[][][0](a←aabbc,aabcc):value[][][1](b←abbcc일경우);
* count0==3) diff[][][4]=000? or ?000 (con0==2) ⇒ 4개값 같음: 4 of a Kind(type=7)
diff[][][4]=0?00 or 00?0 (con0==1) ⇒ 3개값, 2개값 같음: Full house(type=6)
※ 00?0일 경우 value는 aaabb인데 (a<b), 나중에 두 패가 모두 Full house일 경우
비교할 값(comp)는 큰 수 b가 아닌 더 작지만 3개인 a 이므로,
(diff[][][1]==0)(00?0) → comp[][]=value[][][0](a);
* 그 외 flush여부와 (count1==4)여부를 확인하여 Straight(type=4), Flush(type=5), Straight Flush(type=8) 체크.
두 개 이상의 type에 속할 경우 type 번호가 더 높은 쪽에 속하도록 코딩.
어느 타입에도 속하지 않으면 High Card(type=0) : Default로 설정
<win 함수>
* 변수를 type[][], comp, comp2, value 순서대로 이용하여 승패 결정
package h_Poker_Hands;
import java.util.Scanner;
public class PokerHands {
public static void main(String[] args) {
int N=20; //N:input lines Limit
Scanner in=new Scanner(System.in);
Function F=new Function();
int l, i, hand, L; char c;
String[] input=new String[N];
System.out.println("input. To stop inputting, please input '0'");
for(l=0;l<N;l++){ input[l]=in.nextLine(); if(input[l].charAt(0)=='0') break;} L=l; /*Input*/
int[][][] value=new int[L][2][5]; //value[line][hand][i]
boolean[][] flush=new boolean[L][2]; //flush[line][hand]
int[][] type=new int[L][2]; //type[line][hand]
int[][] comp=new int[L][2]; //compared number: comp[line][hand] ←2 hands=the same type.
int[][] comp2=new int[L][2]; //2 hands=both 2 pairs && both comps are the same → compare comp2
int[] result=new int[L];
F.input_to_value(input, value, flush);
F.typef(value, flush, type, comp, comp2);
F.win(type, comp, comp2, value, result);
for(l=0;l<L;l++){
//System.out.print(result[l]+" ");
switch(result[l]){
case 0: System.out.print("Black wins."); break;
case 1: System.out.print("White wins."); break;
case 2: System.out.print("Tie. "); break;
}
System.out.println();
/*PRINT the Process*//*
for(hand=0;hand<2;hand++){
for(i=0;i<5;i++) System.out.print((value[l][hand][i]<10?" ":"")+value[l][hand][i]+" ");
System.out.print("type:"+type[l][hand]+" comp:"+((comp[l][hand]<10)?" ":"")+comp[l][hand]);
System.out.print(((hand==0)?" (vs) ":"\n"));
}
*/
}
}
}
package h_Poker_Hands;
import h_Poker_Hands1.Hand;
public class Function {
int l, hand, i,j,k;
int c_to_v(char c){ //char to value function
int n=(int)c;
if(n>=50 && n<=57) return (n-48); //(int)'2'==50, (int)'9'==57
else
switch(c){
case'T': return 10; case'J': return 11;
case'Q': return 12; case'K': return 13;
case'A': return 14; default: return 0; //0 couldn't be returned.
}
}
void input_to_value(String[] input, int[][][] value, boolean[][] flush){
int L=value.length, ia=0,ib=0, temp;
char c, suit='0';
boolean suit_check=true;
for(l=0;l<L;l++){
for(hand=0; hand<2; hand++){
/*input[l] → value[l][hand][5]*/
for(i=hand*5, j=0, suit_check=true; i<(hand+1)*5; i++,j++){
c=input[l].charAt(i*3);
value[l][hand][j]=c_to_v(c);
}
/*flush CHECK*/
for(i=hand*5,j=0;i<(hand+1)*5;i++,j++){
if(j==0) suit=input[l].charAt(i*3+1);
else if(input[l].charAt(i*3+1)!=suit){ flush[l][hand]=false; break;}
} if(j==5) flush[l][hand]=true;
/*ORDERING THE VALUES IN A HAND*/
for(j=0;j<4;j++) for(k=1;j+k<5;k++)
if(value[l][hand][j]>value[l][hand][j+k]){
temp=value[l][hand][j];
value[l][hand][j]=value[l][hand][j+k];
value[l][hand][j+k]=temp;
}
}
}
}
void typef(int[][][] value, boolean[][] flush, int[][] type, int[][] comp, int[][]comp2){
int L=value.length, count0,count1,con0,compare_num=0; //con0: continuous 0 of diff
int[][][] diff=new int[L][2][4];
for(l=0;l<L;l++) for(hand=0;hand<2;hand++){
count0=0; count1=0; con0=0;
type[l][hand]=0; comp[l][hand]=value[l][hand][4]; //0: HighCard ←Default
for(j=0;j<4;j++){
diff[l][hand][j]=value[l][hand][j+1]-value[l][hand][j];
switch(diff[l][hand][j]){
case 0:
count0++; //count0 of diff : a pair of values are the same.
if(j>0 && diff[l][hand][j-1]==0) con0++; //con0: continuous 0
if(compare_num<value[l][hand][j]) compare_num=value[l][hand][j];
break;
case 1: count1++; break; } //if(count1==4) → Straight
}
if(count0>0) comp[l][hand]=compare_num; //count0 of diff → comp: pair number
switch(count0){
case 1: type[l][hand]=1;
break; //1:One Pair
case 2:
if(con0==1) type[l][hand]=3; //3: 3 of a kind
else{type[l][hand]=2; //2:Two Pairs
comp2[l][hand]=(diff[l][hand][0]==0)?value[l][hand][0]:value[l][hand][1];
} //comp2: both 2 hands are Two Pairs && both comps are the same → compare comp2
break;
case 3:
if(con0==2) type[l][hand]=7; //7: 4 of a kind
else{type[l][hand]=6; //6: Full house
if(diff[l][hand][1]==0) comp[l][hand]=value[l][hand][0];
//full house) diff:0010 → value:aaabb → comp=a;(a<b, but not b)
}
break;
}
if(count1==4 || flush[l][hand]){
if(count1==4 && flush[l][hand]) type[l][hand]=8; //8:Straight Flush
else if(type[l][hand]<4){
if(flush[l][hand]) type[l][hand]=5; //5:flush
else if(count1==4) type[l][hand]=4; //4:Straight
}
comp[l][hand]=value[l][hand][4]; //compare_number=the highest number
}
}
}
void win(int[][] type, int[][] comp, int[][] comp2, int[][][]value, int[] result){
int L=type.length;
for(l=0;l<L;l++){ //result= 0:Black wins. 1:White wins. 2:Tie.
if(type[l][0]!=type[l][1]) result[l]=(type[l][0]>type[l][1])?0:1;
else{
if(comp[l][0]!=comp[l][1]) result[l]=(comp[l][0]>comp[l][1])?0:1;
else if(type[l][0]==2 && comp2[l][0]!=comp2[l][1]) result[l]=(comp2[l][0]>comp2[l][1])?0:1;
else{
for(j=4; j>=0 && value[l][0][j]==value[l][1][j]; j--);
if(j==-1) result[l]=2; //2: Tie. ←all values are the same.
else result[l]=(value[l][0][j]>value[l][1][j])?0:1; //using the rules for High Card.
}
}
}
}
}
#입출력예시 ( /*PRINT the Process*//* */ 풀었을 때)
input. To stop inputting, please input '0'
2H 3D 5S 9C KD 2C 3H 4S 8C AH
2H 4S 4C 2D 4H 2S 8S AS QS 3S
2H 3D 5S 9C KD 2C 3H 4S 8C KH
2H 3D 5S 9C KD 2D 3H 5C 9S KH
0
White wins.
2 3 5 9 13 type:0 comp:13 (vs) 2 3 4 8 14 type:0 comp:14
Black wins.
2 2 4 4 4 type:6 comp: 4 (vs) 2 3 8 12 14 type:5 comp:14
Black wins.
2 3 5 9 13 type:0 comp:13 (vs) 2 3 4 8 13 type:0 comp:13
Tie.
2 3 5 9 13 type:0 comp:13 (vs) 2 3 5 9 13 type:0 comp:13
먼저 우위에 있는 결과에 대해 점수를 부여합니다. 이때 스트레이트플러쉬는 스트레이트의 점수 + 플러쉬의 점수가 되게, 풀하우스는 스리카인드 + 원페어가 투페어는 원페어 + 원페어가 되게 합니다. 또한 각 등급의 점수대는 넉넉하게 주고, 같은 등급에서 비교가 가능하도록 해당 패의 카드점수를 추가해줍니다.
그런다음, 패에 포함된 카드 높은순, 패에 포함되지 않은 카드높은순으로 붙여서 튜플을 만들고 이를 점수와 같이 리턴합니다. (파이썬은 튜플을 비교할 수 있습니다.)
from urllib.request import urlopen
'''
royal-flush 500000
straight-flush 250000
four-card 170000
full-house 160000
flush 130000
straight 120000
three-cards 110000
two-pair 100000
one-pair 50000
high-card 0
'''
def calculate(cards):
priorities = "23456789TJQKA"
def cardNumber(card):
return priorities.index(card[0]) + 2
cards.sort(key=cardNumber, reverse=True)
numbers = [0] * 15
patterns = dict(zip('CHSD', [0]*4))
order = ''.join((card[0] for card in cards))
for card in cards:
patterns[card[1]] += 1
numbers[cardNumber(card)] += 1
if order == 'TJQKA' and [x for x in numbers if x is 5]:
return 50000000, order
score = 0
# straight flush: 25000
# four of a kind: 17000
s = [x for x in cards if numbers[cardNumber(x)] is 4]
if s:
score += 170000
score += cardNumber(s[0])
order = ''.join([x[0] for x in s]) + ''.join([x[0] for x in cards if x not in s])
# flush: 13000
s = [x for x in cards if patterns[x[1]] is 5]
if s:
score += 130000
score += cardNumber(order[0])
# straight: 12000
if order[::-1] in priorities:
score += 120000
score += cardNumber(order[0])
# three of kind: 11000
s = [x for x in cards if numbers[cardNumber(x)] is 3]
if s:
score += 110000
score += cardNumber(s[0])
order = ''.join([x[0] for x in s]) + ''.join([x[0] for x in cards if x not in s])
# two pairs: 10000
# one pairs: 5000
s = [x for x in cards if numbers[cardNumber(x)] is 2]
for _ in s:
score += 25000
if s:
score += max([cardNumber(x) for x in s])
order = ''.join([x[0] for x in s]) + ''.join(x[0] for x in cards if x not in s)
# highcard
order_number = tuple((priorities.index(x) + 2 for x in order))
return score, order_number
def duel(data):
b = calculate(data.split()[:5])
w = calculate(data.split()[5:])
return b > w
m = 0
with urlopen('http://euler.synap.co.kr/files/poker.txt') as f:
for line in f.readlines():
m += 1 if duel(line.decode().strip()) else 0
print(m)
'''
파이썬3.5.1입니다.
위에 나온 링크로 테스트 해봤더니 379번이 나오더라고요.
코드 보시면서 오류 있으시면 댓글로 알려주세요
'''
shape = ('C','D','H','S')
numbers = ('2','3','4','5','6','7','8','9','T','J','Q','K','A')
cardclass = ('HC','OP','TP','TH','ST1','ST2','ST3','FL','FH','FC','SF1','SF2','SF3')
straight = [tuple(numbers[x+i] for i in range(5)) for x in range(9)]
def cardit(l):
dic = []
for i in l:
dic.append((shape.index(i[1]),numbers.index(i[0])))
return sorted(dic)
def check(card):
cardshape = [card[x][0] for x in range(len(card))]
cardnumbr = [card[x][1] for x in range(len(card))]
a = len(set(cardshape))
b = len(set(cardnumbr))
print(a,b,cardshape,cardnumbr)
if a >= 2 and b == 5:
for i in range(len(card)):
card[i] = tuple(reversed(card[i]))
card.sort()
return ('HC',numbers[card.pop()[0]],cardnumbr)
elif a >= 2 and b == 4:
for i in cardnumbr:
if cardnumbr.count(i) == 2:
return ('OP',numbers[i],cardnumbr)
elif a >= 2 and b == 3:
for i in cardnumbr:
if cardnumbr.count(i) == 3:
return ('TH',numbers[i],cardnumbr)
elif cardnumbr.count(i) == 2:
p = set()
for i in cardnumbr:
if cardnumbr.count(i) == 2:
p.add(i)
p = list(p)
return ('TP',(numbers[int(p[0])],numbers[int(p[1])]),cardnumbr)
elif a >= 2 and b == 2:
for i in set(cardnumbr):
if cardnumbr.count(i) == 3 or cardnumbr.count(i) == 2:
return ('FH',tuple(map(numbers.__getitem__,set(cardnumbr))),cardnumbr)
elif cardnumbr.count(i) == 4:
return ('FC',numbers[i],cardnumbr)
elif tuple(sorted(cardnumbr)) in straight or tuple(sorted(cardnumbr)) == ('2','3','4','5','A') \
or tuple(sorted(cardnumbr)) == ('A','J','K','Q','T'):
if len(set(cardshape)) == 1:
if tuple(sorted(cardnumbr)) == ('A','J','K','Q','T'):
return ('SF3','0',cardnumbr)
elif tuple(sorted(cardnumbr)) == ('2','3','4','5','A'):
return ('SF2','0',cardnumbr)
else:
return ('SF1',numbers[numbers.index(min(cardnumbr))+4],cardnumbr)
else:
if tuple(sorted(cardnumbr)) == ('A','J','K','Q','T'):
return ('ST3','0',cardnumbr)
elif tuple(sorted(cardnumbr)) == ('2','3','4','5','A'):
return ('ST2','0',cardnumbr)
else:
return ('ST1',numbers[numbers.index(min(cardnumbr))+4],cardnumbr)
elif a == 1:
return('FL',numbers[max(numbers.index(numbers[i]) for i in cardnumbr)],cardnumbr)
def compare(B,W):
B = check(cardit(B))
W = check(cardit(W))
if cardclass.index(B[0]) > cardclass.index(W[0]):
return 'Black wins.'
elif cardclass.index(B[0]) < cardclass.index(W[0]):
return 'White wins.'
else:
if numbers.index(B[1]) > numbers.index(W[1]):
return 'Black wins.'
elif numbers.index(B[1]) < numbers.index(W[1]):
return 'White wins.'
else:
if sorted(B[2],reverse=True) > sorted(W[2],reverse=True):
return 'Black wins.'
elif sorted(B[2],reverse=True) < sorted(W[2],reverse=True):
return 'White wins.'
else:
return 'Tie.'
c = input().split()
B,W = c[:5],c[5:]
print(compare(B,W))
public class Poker
{
public List<string> Black { get; set; }
public List<string> White { get; set; }
public Poker(List<string> black, List<string> white)
{
Black = black;
White = white;
}
}
public bool IsOnePairCard(List<int> input)
{
return input.GroupBy(i => i).Count(i => input.Count(c => i.Key == c) == 2) == 1;
}
public bool IsTwoPairCard(List<int> input)
{
return input.GroupBy(i => i).Count(i => input.Count(c => i.Key == c) == 2) == 2;
}
public bool IsThreeCard(List<int> input)
{
return input.GroupBy(i => i).Count(i => input.Count(c => i.Key == c) == 3) == 1;
}
public bool IsStraightCard(List<int> input)
{
}
Ruby
하이카드~스트레이트플러쉬 각각에 0~8까지 스코어 부여, [플레이어 스코어, 역정렬된 카드] 형태로 만든 뒤 <=> 로 비교해서 승자 확인.
to_n = "23456789TJQKA".chars.zip(2..14).to_h
hand = ->cards do
ranks, suits = cards.map(&:chars).transpose
pairs, nums = ranks.map(&to_n).group_by {|_|_}.
map {|k,g| [g.size,k] }.sort.reverse.transpose
kind = %w(11111 2111 221 311 32 41).zip([0,1,2,3,6,7]).to_h[pairs.join]
strt = 4 if nums.each_cons(2).all? {|i,j| i == j.next }
flsh = 5 if suits.uniq.one?; stfl = 8 if strt && flsh
[[kind, strt, flsh, stfl].compact.max, nums]
end
play_poker = ->file,games=File.readlines(file).map(&:split) do
prt_result = ->idx { puts %w(Tie. Black\ wins. White\ wins.)[idx] }
games.map {|cards| hand[cards[0,5]] <=> hand[cards[5,5]] }.each &prt_result
end
Test
# mocking file
test_data = ["2H 3D 5S 9C KD 2C 3H 4S 8C AH\n",
"2H 4S 4C 2D 4H 2S 8S AS QS 3S\n",
"2H 3D 5S 9C KD 2C 3H 4S 8C KH\n",
"2H 3D 5S 9C KD 2D 3H 5C 9S KH\n"]
allow(File).to receive(:readlines).and_return(test_data)
results = "White wins.\nBlack wins.\nBlack wins.\nTie.\n"
expect{ play_poker["game_data.txt"] }.to output(results).to_stdout
Output
play_poker["input.txt"]
White wins.
Black wins.
Black wins.
Tie.
흠냐.... ㅠㅠ 왜 377번이 나오는 걸가 ...
찾기 귀찮아서.. 여기 까지만.....
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_COLS 100000
int mapping(char c);
int highcard(char* player1, char* player2);
int pokerhands(char* player, int card[]);
void sort(int n[]);
int b[6], w[6];
int b_count=0;
void main() {
FILE* f = fopen("input.txt", "rt");
char s[MAX_COLS];
while (fgets(s, MAX_COLS, f) != NULL) {
int result = 0;
char black[15];
char white[15];
white[14] = '\0';
black[14] = '\0';
memcpy(black, s, sizeof(char) * 14);
memmove(white, s+15, sizeof(char) * 14);
int j=0;
for(int i=0;i<13;i=i+3) {
b[j] = mapping(black[i]);
j++;
}
sort(b);
j = 0;
for(int i=0;i<13;i=i+3) {
w[j] = mapping(white[i]);
j++;
}
sort(w);
int rw, rb;
rb = pokerhands(black, b);
rw = pokerhands(white, w);
if(rb > rw)
b_count++;
else if(rb < rw)
printf("");//printf("White win!!\n");
else if(rb == rw && rb!=0) {
if(b[5] > w[5])
b_count++;
/*if(b[5] < w[5])
printf("White win!!\n");
if(b[5] == w[5])
printf("tie!!\n");*/
}
else {
int result = highcard(black, white);
if(result == 0)
b_count++;
/*else if(result == 1)
printf("White win!!\n");
else
printf("tie!!\n");*/
}
}
printf("total result b win %d", b_count);
}
// 0 player1 win || 1 player2 win || 2 tie
int highcard(char* player1, char* player2) {
int result = 2;
int index = 4;
while(index>=0) {
if(b[index] > w[index]) {
result = 0;
break;
}
if(b[index] < w[index]) {
result = 1;
break;
}
if(b[index] == w[index]) index--;
}
return result;
}
//straigt flush 8
//four card 7
//full house 6
//flush 5
//straigt 4
//three card 3
//two pair 2
//one pair 1
int pokerhands(char* player, int card[]) {
bool straight_flush = true;
bool flush = true;
bool straight = true;
char temp = player[1];
for(int i=4;i<13;i=i+3) {
if(temp != player[i]) {
straight_flush = false;
flush = false;
}
temp = player[i];
}
for(int i=0 ; i<5 ;i++) {
if(card[0]+i != card[i]) {
straight_flush = false;
straight = false;
}
}
if(straight_flush) {
card[5] = card[4];
//printf("straight flush!!!\n");
return 8;
}
//------------------------------------
bool four_card = false;
bool three_card = false;
bool one_pair = false;
int count = 0;
for(int i=0 ; i<13 ;i=i+3) {
count = 0;
for(int j=0 ; j<13 ;j=j+3) {
if(mapping(player[i]) == mapping(player[j])) {
count++;
if(4==count) {
four_card = true;
card[5] = mapping(player[j]);
}
if(3==count) {
three_card = true;
card[5] = mapping(player[j]);
}
if(2==count) {
one_pair = true;
card[5] = mapping(player[j]);
}
}
}
}
if(four_card) {
//printf("four card!!!!\n");
return 7;
}
//------------------------------------
//------------------------------------
bool full_house = false;
bool two_pair = false;
int f=0;
int j=0;
for(int i=0;i<5;i++) {
if(card[j] == card[i])
continue;
else {
j = i;
f++;
}
}
if(f == 1) full_house = true;
if(f == 2) two_pair = true;
if(full_house) {
card[5] = card[2];
//printf("full house!!!!\n");
return 6;
}
//------------------------------------
if(flush) {
card[5] = card[4];
//printf("flush!!!!\n");
return 5;
}
if(straight) {
card[5] = card[4];
//printf("straight!!!!\n");
return 4;
}
if(three_card) {
//printf("three card!!!!\n");
return 3;
}
if(two_pair) {
card[5] = card[3];
//printf("two_pair!!!!\n");
return 2;
}
if(one_pair) {
//printf("one_pair!!!!\n");
return 1;
}
return 0;
}
int mapping(char c) {
int val = 0;
if(c=='A') val = 14;
else if(c=='K') val = 13;
else if(c=='Q') val = 12;
else if(c=='J') val = 11;
else if(c=='T') val = 10;
else val = c-48;
return val;
}
void sort(int n[]) {
int min = 100;
int temp;
int index = 0;
for(int i = 0 ; i < 5; i++) {
min = 100;
for(int j = i ; j<5; j++) {
if(min > n[j]) {
min = n[j];
index = j;
}
}
temp = n[i];
n[i] = n[index];
n[index] = temp;
}
}
파일 입출력을 활용했습니다.
// 포커 카드 - C#
using System;
using System.IO;
namespace Poker
{
class Program
{
static void checker(string data, ref int result, ref int[] modi) // result와 modi 지정 및 판정.
{
int[] num = new int[5]; // 숫자를 저장하는 배열
char[] shape = new char[5]; // 모양을 저장하는 배열.
for (int i = 0; i < 5; i++)
{
num[i] = grader(data[i * 3]); // 카드 숫자의 문자를 수치로 변경.
shape[i] = data[i * 3 + 1];
}
result = samefinder(num, ref modi);// 여기서 modi 배열도 정리함.
if (result == 0)
result = straightfinder(num); // 스트레이트 체크.
if (flushfinder(shape)) // 플러시 체크
if (result == 5) // 스트레이트면 스트레이트 플러시로
result = 8;
else
result = 4; // 그냥 플러시로
/* result 값에 대하여
* 하이 카드 : 됐고 가장 높은 거 ...0
* 원 페어 : 한 쌍의 같은 카드 ...1
* 투 페어 : 두 쌍의 같은 카드 ...2
* 쓰리 카드 : 세 개의 같은 카드 ...3
* 스트레이트 : 연속되는 다섯 개의 카드 ...4
* 플러시 : 무늬가 같은 다섯 개의 카드 ...5
* 풀 하우스 : 세 개 두 개씩 같은 카드 ...6
* 포 카드 : 네 개가 같은 카드 ...7
* 스트레이트 플러시: 무늬가 같고 연속되는 다섯 개의 카드 ...8 */
}
static int grader(int num) // 카드 문자를 우선 순위의 수치로 변경.
{
switch (num)
{
case 'A': return 14;
case 'K': return 13;
case 'Q': return 12;
case 'J': return 11;
case 'T': return 10;
case '9': return 9;
case '8': return 8;
case '7': return 7;
case '6': return 6;
case '5': return 5;
case '4': return 4;
case '3': return 3;
case '2': return 2;
default: return 0;
}
}
static int samefinder(int[] num, ref int[] modi) // 같은 숫자 찾기 및 modi 정렬.
{
int same1 = 0, same2 = 0; // 같은 숫자의 값을 저장
int counter1 = 0, counter2 = 0; // 같은 숫자가 나온 정도를 저장
int result = 0;
for (int i = 0; i < 4; i++)
for (int j = i + 1; j < 5; j++)
if (num[i] == num[j])
{
if (same1 == 0)
same1 = num[i];
else if (same1 != num[i])
same2 = num[i];
if (num[i] == same1)
counter1++;
else if (num[1] == same2)
counter2++;
}
// 둘 같음 1, 셋 같음 3, 넷 같음 6.
if ((counter1 == 0 && counter2 == 1) || (counter1 == 1 && counter2 == 0)) // 원 페어
result = 1;
else if (counter1 == 1 && counter2 == 1) // 투 페어
result = 2;
else if ((counter1 == 0 && counter2 == 3) || (counter1 == 3 && counter2 == 0)) // 쓰리 카드
result = 3;
else if ((counter1 == 1 && counter2 == 3) || (counter1 == 3 && counter2 == 1)) // 풀하우스
result = 6;
else if ((counter1 == 0 && counter2 == 6) || (counter1 == 6 && counter2 == 0)) // 포 카드
result = 7;
else
result = 0;
// modi 값 설정.
Array.Sort(num); // num을 적은 순으로 정렬, modi에 할당하기 용이하게 한다.
if (result == 6) // 풀하우스: 3개 같은 거 -> 2개 같은 거
if (counter1 == 3)
{
modi[0] = same1;
modi[1] = same2;
}
else
{
modi[0] = same2;
modi[1] = same1;
}
else if (result == 2) // 투 페어: 같은 거 중 큰 거 -> 같은 거 중 작은 거 -> 나머지 하나
{
if (counter1 > counter2)
{
modi[0] = same1;
modi[1] = same2;
}
else
{
modi[0] = same2;
modi[1] = same1;
}
modi[2] = num[4];
}
else if (result != 0) // 같은 거 -> 나머지
{
if (counter1 > counter2)
modi[0] = same1;
else
modi[0] = same2;
for (int i = 1; i < 5; i++)
modi[i] = num[4 - i];
}
else // 무조건 큰 것부터
for (int i = 0; i < 5; i++)
modi[i] = num[4 - i];
return result;
}
static int straightfinder(int[] num) // 스트레이트 탐색.
{
Array.Sort(num);
for (int i = 0; i < 4; i++)
if (num[i] + 1 != num[i + 1])
return 0;
return 5;
}
static bool flushfinder(char[] shape) // 플러시 탐색.
{
for (int i = 0; i < 4; i++)
for (int j = i + 1; j < 5; j++)
if (shape[i] != shape[j])
return false;
return true;
}
static void Main(string[] args)
{
int black_result = 0; int[] black_modi = { 0, 0, 0, 0, 0 };
int white_result = 0; int[] white_modi = { 0, 0, 0, 0, 0 };
// result는 모양 판정 결과, modi는 번호 우선 순위에 대한 배열.
FileStream fs = File.Create("data.txt"); fs.Close(); // 입력 파일 생성
Console.WriteLine("Write your data on data.txt, and press any key.");
// 저 파일에 데이터를 쓴 뒤
Console.ReadKey();
StreamReader reader = new StreamReader("data.txt"); // 파일 읽고
while (true)
{
if (reader.Peek() == -1) // 파일 끝이면 나가기
break;
string data = reader.ReadLine(); // 일단 한 줄 가져오기
checker(data.Remove(14, 15), ref black_result, ref black_modi); // 뒷부분을 잘라 Black 체크.
checker(data.Remove(0, 15), ref white_result, ref white_modi); // 앞부분을 잘라 White 체크.
// result를 이용해 승패 체크
if (black_result > white_result)
Console.WriteLine("Black wins.");
else if (black_result < white_result)
Console.WriteLine("White wins.");
else // modi를 이용한 승패 체크.
{
for (int i = 0; i < 5; i++)
if (black_modi[i] != white_modi[i])
{
if (black_modi[i] > white_modi[i])
Console.WriteLine("Black wins.");
else
Console.WriteLine("White wins.");
break;
}
else
if (i == 4)
Console.WriteLine("Tie.");
}
}
}
}
}
Python3
hand의 숫자들을 큰 순서로 정렬한 nums와, nums를 카운팅한 pairs를 사용했습니다.
예를 들어 예시 입력의 두 번째 줄 Black의 hand가 2H 4S 4C 2D 4H 이고 nums, pairs는 다음과 같습니다.
nums = 4, 4, 4, 2, 2
pairs = (4, 3) (2, 2) : 4가 3장, 2가 2장이라는 뜻
examine함수는 (등급, 같은 등급일 때 차례로 비교할 숫자들) 을 리턴합니다.
hand_prio = ['stifl', 'four card', 'full house', 'flush', 'straight', 'three card', 'two pair', 'one pair', 'high card']
num_prio = 'AKQJT98765432'
def examine(hand):
isflush = lambda x: len(set(x)) == 1
isstraight = lambda x: ''.join(x) in (num_prio + 'A')
nums = sorted([x[0] for x in hand], key = lambda x : num_prio.index(x))
images = [x[1] for x in hand]
pairs = list(filter(lambda x: x[1] > 0, [(n, nums.count(n)) for n in num_prio]))
pairs.sort(key = lambda x : x[1], reverse = True)
rnums = list(filter(lambda x: x != pairs[0][0], nums)) # nums에서 첫 번쨰 페어의 숫자 제외
#print(nums, pairs)
if isflush(images) and isstraight(nums): return 'stifl', [nums[0]]
elif pairs[0][1] is 4: return 'four card', [pairs[0][0]]
elif pairs[0][1] is 3 and pairs[1][1] is 2: return 'full house', [pairs[0][0]]
elif isflush(images): return 'flush', nums
elif isstraight(nums): return 'straight', [nums[0]]
elif pairs[0][1] is 3: return 'three card', [pairs[0][0]]
elif pairs[0][1] is 2 and pairs[1][1] is 2: return 'two pair', [pairs[0][0]] + rnums
elif pairs[0][1] is 2: return 'one pair', [pairs[0][0]] + rnums
else: return 'high card', nums
def judge(black, white):
b_rank = hand_prio.index(black[0])
w_rank = hand_prio.index(white[0])
if b_rank == w_rank and black[1] == white[1]:
return "Tie."
elif b_rank < w_rank or b_rank == w_rank and black[1] < white[1]:
return "Black wins."
else:
return "White wins."
inp = \
"""2H 3D 5S 9C KD 2C 3H 4S 8C AH
2H 4S 4C 2D 4H 2S 8S AS QS 3S
2H 3D 5S 9C KD 2C 3H 4S 8C KH
2H 3D 5S 9C KD 2D 3H 5C 9S KH"""
for line in inp.split('\n'):
cards = line.split()
print(judge(examine(cards[:5]), examine(cards[5:])))
def hand(card):
cdnum = {'T':10,'J':11,'Q':12,'K':13,'A':14}
num, sh = [], []
for i in card: num.append(i[0]); sh.append(i[1])
num = sorted(((cdnum[i] if i in cdnum else int(i)) for i in num), reverse=True)
nc = {i:num.count(i) for i in set(num)}
rep_val = lambda x: sorted((i for i in nc if nc[i] == x), reverse=True)
st = bin(sum(2**i for i in num)).count('11111')
fl = True if len(set(i for i in sh)) == 1 else False
if st and fl: return 8, num
elif 4 in nc.values(): return 7, rep_val(4)
elif sorted(nc.values()) == [2,3]: return 6, rep_val(3)
elif fl: return 5, num
elif st: return 4, num
elif 3 in nc.values(): return 3, rep_val(3)
elif sorted(nc.values()) == [1,2,2]: return 2, rep_val(2) + rep_val(1)
elif 2 in nc.values(): return 1, rep_val(2) + rep_val(1)
else: return 0, num
def winner(bc, wc):
bh, wh = hand(bc), hand(wc)
if bh == wh: print('Tie.'); return 'Tie'
elif bh > wh: print('Black wins.'); return 'Black'
elif wh > bh: print('White wins.'); return 'White'
sample = open('D:/temp/poker.txt','r',encoding='utf8').read()
cdli = sample.split('\n')
print('{} Black win'.format(len([i for i in cdli if winner(i.split()[:5], i.split()[5:]) == 'Black'])))
결과
...
Black wins.
Black wins.
Tie.
376 Black win
점수는 족보 한계단이 올라갈때마다 100점씩 높은 점수를 부여하고 점수 이외의 두자리 숫자는 해당 족보의 높은 카드 값을 부여하여 단순히 점수만 비교해도 승패여부를 판단할 수 있습니다.
기존의 표식을 뒷자리는 무늬, 앞자리는 숫자로 바꿔서 점수를 매깁니다. 표기법을 바꾸는 함수 대신 random하게 카드를 뽑는 형식으로 만들었습니다.
transf.deck <- function(x){
cmb_deck <- matrix(ncol = 2, nrow = length(x))
spt_deck <- strsplit(x, '')
for (i in seq(length(x))){
cmb_deck[i, 1] <- spt_deck[[i]][1]
cmb_deck[i, 2] <- spt_deck[[i]][2]
}
cmb_deck <- gsub('S', 1, cmb_deck)
cmb_deck <- gsub('D', 2, cmb_deck)
cmb_deck <- gsub('H', 3, cmb_deck)
cmb_deck <- gsub('C', 4, cmb_deck)
cmb_deck <- gsub('J', 11, cmb_deck)
cmb_deck <- gsub('Q', 12, cmb_deck)
cmb_deck <- gsub('K', 13, cmb_deck)
cmb_deck <- gsub('A', 14, cmb_deck)
rem_deck <- rep(NA, length(x))
for (i in seq(length(x))){
rem_deck[i] <- as.numeric(paste(cmb_deck[i, 1], cmb_deck[i, 2], sep = ''))
}
return(rem_deck)
}
deck <- c(141, 21, 31, 41, 51, 61, 71, 81, 91, 101, 111, 121, 131,
142, 22, 32, 42, 52, 62, 72, 82, 92, 102, 112, 122, 132,
143, 23, 33, 43, 53, 63, 73, 83, 93, 103, 113, 123, 133,
144, 24, 34, 44, 54, 64, 74, 84, 94, 104, 114, 124, 134)
shuffle <- sample(c(1:52), 10)
white <- sort(deck[head(shuffle, 5)])
black <- sort(deck[tail(shuffle, 5)])
card.pat <- function(x){
return(x %% 10)
}
card.num <- function(x){
return(x %/% 10)
}
pk <- function(x){
if (all(card.pat(x) == card.pat(x[1])) & all(c(card.num(x[1]):(card.num(x[1]) + 4)) == card.num(x))){
point_pk <- 800 + max(card.num(x))
} else if (all(card.num(x[1:4]) == card.num(x[1])) | all(card.num(x[2:5]) == card.num(x[5]))){
point_pk <- 700 + max(card.num(x))
} else if (all(card.num(x[1:3]) == card.num(x[1])) & all(card.num(x[4:5]) == card.num(x[5]))){
point_pk <- 600 + card.num(x[1])
} else if (all(card.num(x[1:2]) == card.num(x[1])) & all(card.num(x[3:5]) == card.num(x[5]))){
point_pk <- 600 + card.num(x[5])
} else if (all(card.pat(x) == card.pat(x[1]))){
point_pk <- 500 + max(card.num(x))
} else if (all(c(card.num(x[1]):(card.num(x[1]) + 4)) == card.num(x))){
point_pk <- 400 + max(card.num(x))
} else if (all(card.num(x[1:3]) == card.num(x[1])) | all(card.num(x[2:4]) == card.num(x[3])) | all(card.num(x[3:5]) == card.num(x[5]))){
point_pk <- 300 + card.num(x[3])
} else if (length(union(card.num(x), NULL)) == 3){
temp_pair <- which(table(card.num(x)) == 2)
point_pk <- 200 + max(as.numeric(names(temp_pair)))
} else if (length(union(card.num(x), NULL)) == 4){
temp_pair <- which(table(card.num(x)) == 2)
point_pk <- 100 + as.numeric(names(temp_pair))
} else {
point_pk <- card.num(x[5])
}
if (any(card.num(x) == 14)){
du <- x
du[card.num(du) == 14] <- du[card.num(du) == 14] - 130
du <- sort(du)
if (all(card.pat(du) == card.pat(du[1])) & c(card.num(du[1]):(card.num(du[1]) + 5)) == card.num(du)){
point_pk <- 800 + max(card.num(du))
} else if (c(card.num(du[1]):(card.num(du[1]) + 5)) == card.num(du) & point_pk < 400){
point_pk <- 400 + max(card.num(du))
}
}
return(point_pk)
}
pb <- function(x, y){
if (x > y){
print('P1 win')
} else if (y > x){
print('P2 win')
} else if (x > 200 & x < 300){
tp_x <- as.numeric(names(which(table(card.num(x)) == 1)))
tp_y <- as.numeric(names(which(table(card.num(y)) == 1)))
if (x > y){
print('P1 win')
} else if (y < x){
print('P2 win')
}
} else if (x > 100 & x < 200){
tp_x <- max(as.numeric(names(which(table(card.num(x)) == 1))))
tp_y <- max(as.numeric(names(which(table(card.num(y)) == 1))))
if (x > y){
print('P1 win')
} else if (y < x){
print('P2 win')
}
}
}
point_white <- pk(white)
point_black <- pk(black)
pb(point_white, point_black)
python
import random
shape_list = ["c", "s", "h", "d"]
number_list = ["A", "2", "3", "4", "5", "6", "7", "8", "9", "J", "Q", "K"]
deck = [{"shape":s, "number":n} for s in shape_list
for n in number_list]
def straight_flush(player):
if flush(player) == 1:
if straight(player) == 1:
return 1
else:
return 0
def countX(x, num):
def countY(y):
return num.count(y) == x
return countY
def remove_num(x, y, num):
for i in range(y):
num.remove(x)
def four_card(player):
num = [player[0]["number"], player[1]["number"], player[2]["number"], player[3]["number"], player[4]["number"]]
score4 = countX("4", num)
for i in number_list:
flag = score4(i)
if flag == True:
return 1
def full_house(player):
if three_card(player) == 1:
num = [player[0]["number"], player[1]["number"], player[2]["number"], player[3]["number"], player[4]["number"]]
score3 = countX("3", num)
for i in number_list:
flag = score3(i)
if flag == True:
remove_num(i, 3, num)
if num[0] == num[1]:
return 1
def flush(player):
for i in range(4):
if player[i]["shape"] == player[i+1]["shape"]:
pass
else:
return 0
return 1
def straight(player):
num = [player[0]["number"], player[1]["number"], player[2]["number"], player[3]["number"], player[4]["number"]]
if "A" in num:
if "2" in num:
if "3" in num:
if "4" in num:
if "5" in num:
return 1
if "2" in num:
if "3" in num:
if "4" in num:
if "5" in num:
if "6" in num:
return 1
if "3" in num:
if "4" in num:
if "5" in num:
if "6" in num:
if "7" in num:
return 1
if "4" in num:
if "5" in num:
if "6" in num:
if "7" in num:
if "8" in num:
return 1
if "5" in num:
if "6" in num:
if "7" in num:
if "8" in num:
if "9" in num:
return 1
if "6" in num:
if "7" in num:
if "8" in num:
if "9" in num:
if "J" in num:
return 1
if "7" in num:
if "8" in num:
if "9" in num:
if "J" in num:
if "Q" in num:
return 1
if "8" in num:
if "9" in num:
if "J" in num:
if "Q" in num:
if "K" in num:
return 1
else :
return 0
def three_card(player):
num = [player[0]["number"], player[1]["number"], player[2]["number"], player[3]["number"], player[4]["number"]]
score3 = countX(3, num)
for i in number_list:
flag = score3(i)
if flag == True:
return 1
def two_pairs(player):
num = [player[0]["number"], player[1]["number"], player[2]["number"], player[3]["number"], player[4]["number"]]
score2 = countX(2, num)
for i in number_list:
flag = score2(i)
if flag == True:
remove_num(i, 2, num)
if num[0] == num[1]:
return 1
elif num[0] == num[2]:
return 1
elif num[1] == num[2]:
return 1
def one_pair(player):
num = [player[0]["number"], player[1]["number"], player[2]["number"], player[3]["number"], player[4]["number"]]
score2 = countX(2, num)
for i in number_list:
flag = score2(i)
if flag == True:
return 1
def high_card(Black, White):
black_big = big_number_finder(Black)
white_big = big_number_finder(White)
if black_big > white_big:
print("Black이 승리하였습니다")
if black_big < white_big:
print("White가 승리하였습니다")
if black_big == white_big:
print("무승부입니다")
def big_number_finder(player):
num = [player[0]["number"], player[1]["number"], player[2]["number"], player[3]["number"], player[4]["number"]]
if "A" in num:
return 11
elif "K" in num:
return 10
elif "Q" in num:
return 9
elif "J" in num:
return 8
elif "9" in num:
return 7
elif "8" in num:
return 6
elif "7" in num:
return 5
elif "6" in num:
return 4
elif "5" in num:
return 3
elif "4" in num:
return 2
elif "3" in num:
return 1
elif "2" in num:
return 0
def who_is_winner(Black, White): #승리판정
black_score = 0
white_score = 0
if straight_flush(Black) == 1:
black_score = 8
print("Black은 스트레이트 플러쉬입니다")
else:
if four_card(Black) == 1:
black_score = 7
print("Black은 포카드입니다")
else:
if full_house(Black) == 1:
black_score = 6
print("Black은 풀하우스입니다")
else:
if flush(Black) == 1:
black_score = 5
print("Black은 플러쉬입니다")
else :
if straight(Black) == 1:
black_score = 4
print("Black은 스트레이트입니다")
else:
if three_card(Black) == 1:
black_score = 3
print("Black은 쓰리카드입니다")
else:
if two_pairs(Black) == 1:
black_score = 2
print("Black은 투페어입니다")
else:
if one_pair(Black) == 1:
black_score = 1
print("Black은 원페어입니다")
else:
black_score = 0
print("Black은 하이카드입니다")
if straight_flush(White) == 1:
white_score = 8
print("White은 스트레이트 플러쉬입니다")
else:
if four_card(White) == 1:
white_score = 7
print("White은 포카드입니다")
else:
if full_house(White) == 1:
white_score = 6
print("White은 풀하우스입니다")
else:
if flush(White) == 1:
white_score = 5
print("White은 플러쉬입니다")
else :
if straight(White) == 1:
white_score = 4
print("White은 스트레이트입니다")
else:
if three_card(White) == 1:
white_score = 3
print("White은 쓰리카드입니다")
else:
if two_pairs(White) == 1:
white_score = 2
print("White은 투페어입니다")
else:
if one_pair(White) == 1:
white_score = 1
print("White은 원페어입니다")
else:
white_score = 0
print("White은 하이카드입니다")
#승리판정#
if black_score > white_score:
print("Black이 승리하였습니다.")
elif black_score < white_score:
print("white가 승리하였습니다.")
elif black_score == white_score:
if black_score == 0 and white_score == 0:
high_card(Black,White)
same(Black, White, black_score) #do 같은 족보(하이카드 제외)일경우 승리판정
def same(player1, player2, score): #같은 족보일경우(하이카드 제외) 승리판정
if score == 8: #스트레이트 플러쉬
black_score = big_number_finder(Black)
white_score = big_number_finder(White)
if black_score > white_score:
print("Black이 승리하였습니다")
if black_score < white_score:
print("White이 승리하였습니다")
if black_score == white_score:
print("무승부 입니다.")
if score == 7: #포카드
black_score = big_number_finder(Black)
white_score = big_number_finder(White)
if black_score > white_score:
print("Black이 승리하였습니다")
if black_score < white_score:
print("White이 승리하였습니다")
if black_score == white_score:
print("무승부 입니다.")
if score == 6: #풀하우스
black_score = full_house_finder(Black)
white_score = full_house_finder(White)
if black_score > white_score:
print("Black이 승리하였습니다")
if black_score < white_score:
print("White이 승리하였습니다")
if black_score == white_score:
print("무승부 입니다.")
if score == 5: #플러쉬
black_score = big_number_finder(Black)
white_score = big_number_finder(White)
if black_score > white_score:
print("Black이 승리하였습니다")
if black_score < white_score:
print("White이 승리하였습니다")
if black_score == white_score:
print("무승부 입니다.")
if score == 4: #스트레이트
black_score = big_number_finder(Black)
white_score = big_number_finder(White)
if black_score > white_score:
print("Black이 승리하였습니다")
if black_score < white_score:
print("White이 승리하였습니다")
if black_score == white_score:
print("무승부 입니다.")
if score == 3: #쓰리카드
black_score = three_card_finder(Black)
white_score = three_card_finder(White)
if black_score > white_score:
print("Black이 승리하였습니다")
if black_score < white_score:
print("White이 승리하였습니다")
if black_score == white_score:
print("무승부 입니다.")
if score == 2: #투페어
black_pair = two_pairs_finder(Black)
white_pair = two_pairs_finder(White)
if black_pair[0] > black_pair[1]:
bp = 1
elif black_pair[0] < black_pair[1]:
bp = 2
elif white_pair[0] > white_pair[1]:
wp = 3
elif white_pair[0] < white_pair[1]:
wp = 4
if bp == 1 and wp == 3: #black_pair[0], white_pair[0] 비교
if black_pair[0] > white_pair[0]:
print("Black의 승리입니다")
if black_pair[0] < white_pair[0]:
print("White의 승리입니다")
if black_pair[0] == white_pair[0]:
if black_pair[2] > white_pair[2]:
print("Black의 승리입니다")
if black_pair[2] < white_pair[2]:
print("White의 승리입니다")
if black_pair[2] == white_pair[2]:
print("무승부입니다")
elif bp == 1 and wp == 4: #black_pair[0], white_pair[1] 비교
if black_pair[0] > white_pair[1]:
print("Black의 승리입니다")
if black_pair[0] < white_pair[1]:
print("White의 승리입니다")
if black_pair[0] == white_pair[1]:
if black_pair[2] > white_pair[2]:
print("Black의 승리입니다")
if black_pair[2] < white_pair[2]:
print("White의 승리입니다")
if black_pair[2] == white_pair[2]:
print("무승부입니다")
elif bp == 2 and wp == 3: #black_pair[1], white_pair[0] 비교
if black_pair[1] > white_pair[0]:
print("Black의 승리입니다")
if black_pair[1] < white_pair[0]:
print("White의 승리입니다")
if black_pair[1] == white_pair[0]:
if black_pair[2] > white_pair[2]:
print("Black의 승리입니다")
if black_pair[2] < white_pair[2]:
print("White의 승리입니다")
if black_pair[2] == white_pair[2]:
print("무승부입니다")
elif bp == 2 and wp == 4: #black_pair[1], white_pair[1] 비교
if black_pair[1] > white_pair[1]:
print("Black의 승리입니다")
if black_pair[1] < white_pair[1]:
print("White의 승리입니다")
if black_pair[1] == white_pair[1]:
if black_pair[2] > white_pair[2]:
print("Black의 승리입니다")
if black_pair[2] < white_pair[2]:
print("White의 승리입니다")
if black_pair[2] == white_pair[2]:
print("무승부입니다")
if score == 1: #원페어
black_score = one_pair_finder(Black)
white_score = one_pair_finder(White)
if black_score > white_score:
print("Black이 승리하였습니다")
if black_score < white_score:
print("White이 승리하였습니다")
if black_score == white_score:
print("무승부 입니다.")
def one_pair_finder(player):
num = [player[0]["number"], player[1]["number"], player[2]["number"], player[3]["number"], player[4]["number"]]
for n in number_list:
if num.count(n) == 2:
if n == "A":
return 13
if n == "J":
return 10
if n == "Q":
return 11
if n == "K":
return 12
return n
def one_pair_finder2(player):
num = [player[0]["number"], player[1]["number"], player[2]["number"], player[3]["number"], player[4]["number"]]
score = one_pair_finder(player)
if score == 13:
remove_num("A", 2, num)
elif score == 2:
remove_num("2", 2, num)
elif score == 3:
remove_num("3", 2, num)
elif score == 4:
remove_num("4", 2, num)
elif score == 5:
remove_num("5", 2, num)
elif score == 6:
remove_num("6", 2, num)
elif score == 7:
remove_num("7", 2, num)
elif score == 8:
remove_num("8", 2, num)
elif score == 9:
remove_num("9", 2, num)
elif score == 10:
remove_num("J", 2, num)
elif score == 11:
remove_num("Q", 2, num)
elif score == 12:
remove_num("K", 2, num)
for n in number_list:
if num.count(n) == 2:
if n == "A":
return 13
if n == "J":
return 10
if n == "Q":
return 11
if n == "K":
return 12
return n
def remainder_finder(player):
num = [player[0]["number"], player[1]["number"], player[2]["number"], player[3]["number"], player[4]["number"]]
score = one_pair_finder(player)
if score == 13:
remove_num("A", 2, num)
elif score == 2:
remove_num("A", 2, num)
elif score == 3:
remove_num("A", 2, num)
elif score == 4:
remove_num("A", 2, num)
elif score == 5:
remove_num("A", 2, num)
elif score == 6:
remove_num("A", 2, num)
elif score == 7:
remove_num("A", 2, num)
elif score == 8:
remove_num("A", 2, num)
elif score == 9:
remove_num("A", 2, num)
elif score == 10:
remove_num("A", 2, num)
elif score == 11:
remove_num("A", 2, num)
elif score == 12:
remove_num("A", 2, num)
if "A" in num:
remove_num("A", 2, num)
elif "2" in num:
remove_num("A", 2, num)
elif "3" in num:
remove_num("A", 2, num)
elif "4" in num:
remove_num("A", 2, num)
elif "5" in num:
remove_num("A", 2, num)
elif "6" in num:
remove_num("A", 2, num)
elif "7" in num:
remove_num("A", 2, num)
elif "8" in num:
remove_num("A", 2, num)
elif "9" in num:
remove_num("A", 2, num)
elif "J" in num:
remove_num("A", 2, num)
elif "Q" in num:
remove_num("A", 2, num)
elif "K" in num:
remove_num("A", 2, num)
return num
def three_card_finder(player):
num = [player[0]["number"], player[1]["number"], player[2]["number"], player[3]["number"], player[4]["number"]]
for n in number_list:
if num.count(n) == 3:
if n == "A":
return 13
if n == "J":
return 10
if n == "Q":
return 11
if n == "K":
return 12
return n
def two_pairs_finder(player):
one_score = one_pair_finder #첫번째 페어쌍
two_score = one_pair_finder2 #두번째 페어쌍
remainder = remainder_finder(player) #나머지
if remainder == "A":
remainder_score = 13
if remainder == "2":
remainder_score = 2
if remainder == "3":
remainder_score = 3
if remainder == "4":
remainder_score = 4
if remainder == "5":
remainder_score = 5
if remainder == "6":
remainder_score = 6
if remainder == "7":
remainder_score = 7
if remainder == "8":
remainder_score = 8
if remainder == "9":
remainder_score = 9
if remainder == "J":
remainder_score = 10
if remainder == "Q":
remainder_score = 11
if remainder == "K":
remainder_score = 12
return [one_score, two_score, remainder_score]
def full_house_finder(player):
num = [player[0]["number"], player[1]["number"], player[2]["number"], player[3]["number"], player[4]["number"]]
for n in number_list:
if num.count(n) == 3:
if n == "A":
return 13
if n == "J":
return 10
if n == "Q":
return 11
if n == "K":
return 12
return n
pick = random.sample(deck,10)
Black = pick[:5]
White = pick[5:]
print(f"Black: {Black}")
print(f"White: {White}")
who_is_winner(Black, White)
number = {'2':2, '3':3, '4':4, '5':5, '6':6, '7':7, '8':8, '9':9, 'T':10, 'J':11, 'Q':12, 'K':13, 'A':14}
def pair(lst):
dict = {}
for c in lst:
if c[0] not in dict:
dict[c[0]] = 0
dict[c[0]] += 1
pairSu = 3
while pairSu > 1:
pair = 0
for k in dict:
if dict[k]== pairSu:
pair = max(pair, number[k])
if pair>0:
return pair*(10**(pairSu-1))
pairSu -= 1
return 0
def straight(lst):
su = []
for l in lst:
su.append(number[l[0]])
su = sorted(su)
if su==[2,3,4,5,14]:
return 14*(10**3)
for i in range(1,5):
if su[i-1] + 1 != su[i]:
return pair(lst)
return su[-1] * (10**3)
def flush(lst):
cnt = 0
su = number[lst[0][0]]
for c in lst:
if lst[0][1]==c[1]:
cnt += 1
su = max(su, number[c[0]])
if cnt == 5:
return su * (10**4)
return straight(lst)
def fullHouse(lst):
dict = {}
for c in lst:
if c[0] not in dict:
dict[c[0]] = 0
dict[c[0]] += 1
if len(dict)==2:
for k in dict:
if dict[k]==3:
return number[k] * (10**5)
return flush(lst)
def fourcard(lst):
for i in [0, 1]:
cnt = 0
for c in lst:
if lst[i][0]==c[0]:
cnt += 1
if cnt == 4:
return num[lst[i][0]] * (10**6)
return fullHouse(lst)
def straight_flush(lst):
su = []
for l in lst:
if lst[0][1]==l[1]:
su.append(number[l[0]])
else:
return fourcard(lst)
su = sorted(su)
if su==[2,3,4,5,14]:
return 14*(10**7)
for i in range(1,5):
if su[i-1]+1 != su[i]:
return su[-1] * 10000
return su[-1]*(10**7)
def game(black, white):
B = straight_flush(black)
W = straight_flush(white)
if B > W:
return 0
elif B==W and (B<=140 or 20000<B<=1400000):
bsu, wsu = [], []
for i in range(5):
bsu.append(number[black[i][0]])
wsu.append(number[white[i][0]])
bsu, wsu = sorted(bsu), sorted(wsu)
for i in range(4,-1,-1):
if bsu[i]==wsu[i]: continue
elif bsu[i]>wsu[i]: return 0
else: return 1
return 2
return 1
inp = """2H 3D 5S 9C KD 2C 3H 4S 8C AH
2H 4S 4C 2D 4H 2S 8S AS QS 3S
2H 3D 5S 9C KD 2C 3H 4S 8C KH
2H 3D 5S 9C KD 2D 3H 5C 9S KH"""
data = [d.split() for d in inp.split('\n')]
for d in data:
bCards = d[:5]
wCards = d[5:]
res = game(bCards, wCards)
if res==0: print("Black wins.")
elif res==1: print("White wins.")
else: print("Tie.")
JAVA입니다. 같은 값을 가진 카드의 등장 횟수를 값을 키, 등장 횟수를 값으로 하는 hashtable로 저장한 다음, 이를 다시 등장 횟수를 인덱스, 값을 값으로 하는 list로 변환하여 값을 내림차순으로 정렬하였습니다. 그 다음 각 조건을 확인하여 비교 대상이 되는 등장 횟수의 카드의 값들(예를 들어 쓰리 카드에서는 등장 횟수가 3인 카드만, 하이 카드는 등장 횟수가 1인 카드 전체 등)을 valuesToCompare에 넣고, compare 메소드에서 우선 두 Hand의 랭크를 비교하고, 같으면 두 Hand의 valuesToCompare를 우선순위 순으로 비교하는 방식으로 승패를 정했습니다. 실행 결과 black이 376번 승리하였습니다.
package question3.poker_hands;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.List;
public class Main {
public static void main(String[] args) throws FileNotFoundException, IOException {
BufferedReader br = new BufferedReader
(new FileReader(Main.class.getResource("input.txt").getPath()));
Hashtable<Character, Integer> valueToNum = new Hashtable<Character, Integer>();
for (int i = 2; i < 10; i++) {
valueToNum.put(Integer.toString(i).charAt(0), i);
}
valueToNum.put('T', 10);
valueToNum.put('J', 11);
valueToNum.put('Q', 12);
valueToNum.put('K', 13);
valueToNum.put('A', 14);
List<Integer> results = new ArrayList<Integer>();
while(true) {
String line = br.readLine();
if(line == null) {
break;
}
Card[] black = new Card[5];
Card[] white = new Card[5];
String[] cardStrs = line.split(" ");
for (int i = 0; i < 5; i++) {
black[i] = new Card
(cardStrs[i].charAt(1), valueToNum.get(cardStrs[i].charAt(0)));
}
for (int i = 5; i < 10; i++) {
white[i-5] = new Card
(cardStrs[i].charAt(1), valueToNum.get(cardStrs[i].charAt(0)));
}
Hand blackHand = new Hand(black);
Hand whiteHand = new Hand(white);
int result = blackHand.compare(whiteHand);
results.add(result);
}
br.close();
int blackWin = 0;
for (Integer integer : results) {
switch (integer) {
case 1:
System.out.println("Black wins.");
blackWin++;
break;
case -1:
System.out.println("White wins.");
break;
default:
System.out.println("Tie.");
break;
}
}
System.out.println(blackWin);
}
}
package question3.poker_hands;
public class Card {
char kind;
int value;
public Card(char kind, int value) {
this.kind = kind;
this.value = value;
}
}
package question3.poker_hands;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
public class Hand {
Card[] cards;
boolean isFlush;
boolean isStraight;
int maxValue;
int minValue;
Hashtable<Integer, Integer> valueFrequency;
List<List<Integer>> cardCombinations;
//0~4번 인덱스: 빈도수가 1~5회인 카드의 value들 저장
int rank;
List<Integer> valuesToCompare;
public Hand(Card[] cards) {
this.cards = cards;
isFlush = true;
isStraight = false;
maxValue = 0;
minValue = 15; //개별 카드의 값은 14가 최대이므로 minValue는 15부터 시작
rank = 0;
valueFrequency = new Hashtable<Integer, Integer>();
cardCombinations = new ArrayList<List<Integer>>();
for (int i = 0; i < 5; i++) {
cardCombinations.add(new ArrayList<Integer>());
}
valuesToCompare = new ArrayList<Integer>();
readHand();
sortCardCombination();
setRank();
}
void setRank() {
if(isStraight && isFlush) {
//스트레이트 플러쉬
valuesToCompare.add(cardCombinations.get(0).get(0));
rank = 9;
return;
}
if(cardCombinations.get(3).size() == 1) {
//포카드
valuesToCompare.add(cardCombinations.get(3).get(0));
rank = 8;
return;
}
if(cardCombinations.get(2).size() == 1 && cardCombinations.get(1).size() == 1) {
//풀 하우스
valuesToCompare.add(cardCombinations.get(2).get(0));
rank = 7;
return;
}
if(isFlush) {
//플러쉬
valuesToCompare.addAll(cardCombinations.get(0));
rank = 6;
return;
}
if(isStraight) {
//스트레이트
valuesToCompare.add(cardCombinations.get(0).get(0));
rank = 5;
return;
}
if(cardCombinations.get(2).size() == 1) {
//쓰리 카드
valuesToCompare.add(cardCombinations.get(2).get(0));
rank = 4;
return;
}
if(cardCombinations.get(1).size() == 2) {
//투 페어
valuesToCompare.add(cardCombinations.get(1).get(0));
valuesToCompare.add(cardCombinations.get(1).get(1));
valuesToCompare.add(cardCombinations.get(0).get(0));
rank = 3;
return;
}
if(cardCombinations.get(1).size() == 1) {
//원 페어
valuesToCompare.add(cardCombinations.get(1).get(0));
valuesToCompare.addAll(cardCombinations.get(0));
rank = 2;
return;
}
//하이 카드
valuesToCompare.addAll(cardCombinations.get(0));
rank = 1;
return;
}
void readHand() {
char kind = cards[0].kind;
for (Card card : cards) {
if(card.value > maxValue) {
maxValue = card.value;
}
if(card.value < minValue) {
minValue = card.value;
}
valueFrequency.put
(card.value, valueFrequency.getOrDefault(card.value, 0) + 1);
if(card.kind != kind) {
//모든 카드가 같은 종류가 아니므로 플러시가 아님
isFlush = false;
}
}
if(maxValue - minValue == 4 && valueFrequency.keySet().size() == 5) {
//2, 3, 4, 5, 6과 같이 연속하는 5개의 숫자인 경우
isStraight = true;
}
}
void sortCardCombination() {
for (Map.Entry<Integer, Integer> entry : valueFrequency.entrySet()) {
Integer cardValue = entry.getKey();
Integer frequency = entry.getValue();
cardCombinations.get(frequency - 1).add(cardValue);
}
for (List<Integer> list : cardCombinations) {
Collections.sort(list, Collections.reverseOrder());
}
}
int compare(Hand otherHand) {
//자신이 이기면 1, 지면 -1, 비기면 0
if(this.rank != otherHand.rank) {
return (this.rank > otherHand.rank) ? 1 : -1;
}
for (int i = 0; i < this.valuesToCompare.size(); i++) {
if(this.valuesToCompare.get(i) > otherHand.valuesToCompare.get(i)) {
return 1;
}
else if(this.valuesToCompare.get(i) < otherHand.valuesToCompare.get(i)) {
return -1;
}
}
return 0;
}
}