Euler Solution 54

From ProgSoc Wiki

Jump to: navigation, search

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?

Solutions

Python by Althalus

Runtime: 9ms

POKER_HANDS = [ ..... ]

start = time()

def score(hand):
  values = {
       '2':0,'3':1,'4':2,'5':3,'6':4,'7':5,'8':6,
       '9':7,'T':8,'J':9,'Q':10,'K':11,'A':12,
  }
  cards = [0,0,0,0,0,0,0,0,0,0,0,0,0]
  suites = {'H':0,'D':0,'S':0,'C':0}

  # Set up card and hand dicts
  for c in hand:
    cards[ values[ c[0] ] ] += 1
    suites[ c[1] ] +=1

  # Return the cards in order, in case there's a draw in hands.
  ordered = []
  for x in range (12,-1,-1):
    if cards[x] > 0:
      for i in range(cards[x]): ordered.append(x)

  # Score flush (or not)
  if 5 in suites.values(): flush = 1
  else: flush = 0

  #Checkfor a royal flush.
  if cards[8:13].count(1) == 5 and flush: return 900, ordered
  #Check for straight flush
  for x in range(9):
    if cards[x:x+5].count(1) == 5 and flush: return 800+x+5,ordered
  #Check for four of a kind
  if 4 in cards: return 700+cards.index(4), ordered
  #Check for full house
  if 3 in cards and 2 in cards: return 600+cards.index(3),ordered
  #flush
  if flush: return 500,ordered
  #check for straight.
  for x in range(9):
    if cards[x:x+5].count(1) == 5: return 400+x+5,ordered
  if cards[0:4].count(1)+cards[12] == 5 and flush: return 900, ordered
  #check for three of a kind
  if 3 in cards: return 300+cards.index(3),ordered
  #check for two pair
  if cards.count(2) == 2:
    cards.reverse()
    return 200+cards.index(2),ordered
  #Check for one pair
  if 2 in cards: return 100+cards.index(2),ordered
  #No ranking - highest card.
  return ordered[0], ordered

p1 = p2 = 0
for hand in POKER_HANDS:
  s1 = score(hand[:5])
  s2 = score(hand[5:])
  if s1[0] > s2[0]: p1 += 1
  if s1[0] < s2[0]: p2 += 1
  if s1[0] == s2[0]:
    if s1[1] > s2[1]: p1 += 1
    if s1[1] < s2[1]: p2 += 1
print p1, p2
Personal tools