Permalink
Browse files

Solved Problem 54

  • Loading branch information...
1 parent 6fd776f commit 4df851a4a741b74396bfc2116b3c929b3b5f54cc @dhruvbaldawa committed Apr 23, 2012
Showing with 1,129 additions and 0 deletions.
  1. +129 −0 0054-poker-hands.py
  2. +1,000 −0 poker.txt
View
@@ -0,0 +1,129 @@
+"""
+In the card game poker, a hand consists of five cards and
+are ranked, from lowest to highest, in the following way:
+
+High Card: Highest value card.
+One Pair: Two cards of the same value.
+Two Pairs: Two different pairs.
+Three of a Kind: Three cards of the same value.
+Straight: All cards are consecutive values.
+Flush: All cards of the same suit.
+Full House: Three of a kind and a pair.
+Four of a Kind: Four cards of the same value.
+Straight Flush: All cards are consecutive values of same suit.
+Royal Flush: Ten, Jack, Queen, King, Ace, in same suit.
+The cards are valued in the order:
+2, 3, 4, 5, 6, 7, 8, 9, 10, Jack, Queen, King, Ace.
+
+If two players have the same ranked hands then the rank made
+ up of the highest value wins; for example, a pair of eights
+beats a pair of fives (see example 1 below). But if two
+ranks tie, for example, both players have a pair of queens,
+then highest cards in each hand are compared if the highest
+cards tie then the next highest cards are compared, and so on.
+
+The file, poker.txt, contains one-thousand random hands
+dealt to two players. Each line of the file contains ten cards
+(separated by a single space): the first five are Player 1's
+cards and the last five are Player 2's cards. You can assume
+that all hands are valid (no invalid characters or repeated
+cards), each player's hand is in no specific order, and in
+each hand there is a clear winner.
+
+How many hands does Player 1 win?
+"""
+def take_input():
+ f = open("poker.txt").read().splitlines()
+ return f
+
+def poker(hands):
+ "Return a list of winning hands: poker([hand,...]) => [hand,...]"
+ return allmax(hands, key=hand_rank)
+
+def allmax(iterable, key=None):
+ "Return a list of all items equal to the max of the iterable."
+ result, maxval = [], None
+ key = key or (lambda x: x)
+
+ for x in iterable:
+ xval = key(x)
+ if not result or xval > maxval:
+ result, maxval = [x], xval
+ elif xval == maxval:
+ result.append(x)
+ return result
+
+def hand_rank(hand):
+ "Return a value indicating the ranking of a hand."
+ ranks = card_ranks(hand)
+ if straight(ranks) and flush(hand) and max(ranks) == 14:
+ return (9, max(ranks))
+ elif straight(ranks) and flush(hand):
+ return (8, max(ranks))
+ elif kind(4, ranks):
+ return (7, kind(4, ranks), kind(1, ranks))
+ elif kind(3, ranks) and kind(2, ranks):
+ return (6, kind(3, ranks), kind(2, ranks))
+ elif flush(hand):
+ return (5, ranks)
+ elif straight(ranks):
+ return (4, max(ranks))
+ elif kind(3, ranks):
+ return (3, kind(3, ranks), ranks)
+ elif two_pair(ranks):
+ return (2, two_pair(ranks), ranks)
+ elif kind(2, ranks):
+ return (1, kind(2, ranks), ranks)
+ else:
+ return (0, ranks)
+
+def card_ranks(hand):
+ "Return a list of the ranks, sorted with higher first."
+ ranks = ['--23456789TJQKA'.index(r) for r, s in hand]
+ ranks.sort(reverse = True)
+ return [5, 4, 3, 2, 1] if (ranks == [14, 5, 4, 3, 2]) else ranks
+
+def flush(hand):
+ "Return True if all the cards have the same suit."
+ suits = [s for r,s in hand]
+ return len(set(suits)) == 1
+
+def straight(ranks):
+ "Return True if the ordered ranks form a 5-card straight."
+ return (max(ranks)-min(ranks) == 4) and len(set(ranks)) == 5
+
+def kind(n, ranks):
+ """Return the first rank that this hand has exactly n-of-a-kind of.
+ Return None if there is no n-of-a-kind in the hand."""
+ for r in ranks:
+ if ranks.count(r) == n: return r
+ return None
+
+def two_pair(ranks):
+ "If there are two pair here, return the two ranks of the two pairs, else None."
+ pair = kind(2, ranks)
+ lowpair = kind(2, list(reversed(ranks)))
+ if pair and lowpair != pair:
+ return (pair, lowpair)
+ else:
+ return None
+
+def test():
+ "Test cases for the functions in poker program."
+ sf1 = "6C 7C 8C 9C TC".split() # Straight Flush
+ sf2 = "6D 7D 8D 9D TD".split() # Straight Flush
+ fk = "9D 9H 9S 9C 7D".split() # Four of a Kind
+ fh = "TD TC TH 7C 7D".split() # Full House
+ rf = "AH KH QH JH TH".split() # Royal Flush
+ assert poker([sf1, sf2, fk, fh, rf]) == [rf]
+ return 'tests pass'
+
+score = 0
+for x in take_input():
+ cards = x.split()
+ pl1 = cards[:5]
+ pl2 = cards[5:]
+ if pl1 in poker([pl1, pl2]):
+ score += 1
+
+print "Answer is:", score
Oops, something went wrong.

0 comments on commit 4df851a

Please sign in to comment.