summaryrefslogtreecommitdiff
path: root/054.py
diff options
context:
space:
mode:
Diffstat (limited to '054.py')
-rw-r--r--054.py287
1 files changed, 287 insertions, 0 deletions
diff --git a/054.py b/054.py
new file mode 100644
index 0000000..bd7d14f
--- /dev/null
+++ b/054.py
@@ -0,0 +1,287 @@
+
+values = {
+'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
+}
+
+colors = {
+'H': 1,
+'C': 2,
+'S': 3,
+'D': 4
+}
+
+
+def handvalue(hand):
+ return values[hand[0]]*10 + colors[hand[1]]
+
+def count_cards(hand):
+ hand = [ x/10 for x in hand ]
+ counter = { }
+ for c in hand:
+ if c in counter:
+ counter[c] += 1
+ else:
+ counter[c] = 1
+ return counter
+
+def high_card(hand):
+ hand = [ x/10 for x in hand ]
+ hand.sort()
+ return hand[-1]
+
+def is_flush(hand):
+ return (hand[0]%10 == hand[1]%10 == hand[2]%10 == hand[3]%10 == hand[4]%10)
+
+def is_straight(hand):
+ hand = [ x/10 for x in hand ]
+ hand.sort()
+ return (hand[4] == hand[3]+1 == hand[2]+2 == hand[1]+3 == hand[0]+4)
+
+def is_straight_flush(hand):
+ return is_flush(hand) and is_straight(hand)
+
+def is_royal_flush(hand):
+ return is_straight_flush(hand) and high_card(hand) == values['A']
+
+def is_n_of_a_kind(hand, n):
+ counter = count_cards(hand)
+ for c in counter:
+ if counter[c] == n:
+ return True
+ return False
+
+def is_four_of_a_kind(hand):
+ return is_n_of_a_kind(hand, 4)
+
+def is_three_of_a_kind(hand):
+ return is_n_of_a_kind(hand, 3)
+
+def is_one_pair(hand):
+ return is_n_of_a_kind(hand, 2)
+
+def is_two_pairs(hand):
+ counter = count_cards(hand)
+ pairs = 0
+ for c in counter:
+ if counter[c] == 2 or counter[c] == 3:
+ pairs += 1
+ return pairs == 2
+
+def is_full_house(hand):
+ return is_two_pairs(hand) and is_three_of_a_kind(hand)
+
+
+def better_hand(hand1, hand2):
+ # both are straight flush
+ if is_straight_flush(hand1):
+ if high_card(hand1) > high_card(hand2):
+ return 1
+ else:
+ return 2
+
+ # both are four of a kind
+ if is_four_of_a_kind(hand1):
+ count1 = count_cards(hand1)
+ count2 = count_cards(hand2)
+ value4_1 = 0
+ value4_2 = 0
+ for c in count1:
+ if count1[c] == 4:
+ value4_1 = c
+ break
+ for c in count2:
+ if count2[c] == 4:
+ value4_2 = c
+ break
+ if value4_1 > value4_2:
+ return 1
+ else:
+ return 2
+
+ # both are full house
+ if is_full_house(hand1):
+ count1 = count_cards(hand1)
+ count2 = count_cards(hand2)
+ value3_1 = 0
+ value3_2 = 0
+ for c in count1:
+ if count1[c] == 3:
+ value3_1 = c
+ break
+ for c in count2:
+ if count2[c] == 3:
+ value3_2 = c
+ break
+ if value3_1 > value3_2:
+ return 1
+ else:
+ return 2
+
+ # both are flush
+ if is_flush(hand1):
+ hand1 = [ x/10 for x in hand1 ]
+ hand2 = [ x/10 for x in hand2 ]
+ hand1.sort()
+ hand2.sort()
+ for i in range(0, 5):
+ if hand1[4-i] > hand2[4-i]:
+ return 1
+ elif hand2[4-i] > hand1[4-i]:
+ return 2
+ print "ERROR: no winner with hands: ", hand1, hand2 # should never be reached
+
+ # both are straight
+ if is_straight(hand1):
+ if high_card(hand1) > high_card(hand2):
+ return 1
+ else:
+ return 2
+
+ # both are three of a kind
+ if is_three_of_a_kind(hand1):
+ count1 = count_cards(hand1)
+ count2 = count_cards(hand2)
+ value3_1 = 0
+ value3_2 = 0
+ for c in count1:
+ if count1[c] == 3:
+ value3_1 = c
+ break
+ for c in count2:
+ if count2[c] == 3:
+ value3_2 = c
+ break
+ if value3_1 > value3_2:
+ return 1
+ else:
+ return 2
+
+ # both are two pairs
+ if is_two_pairs(hand1):
+ count1 = count_cards(hand1)
+ count2 = count_cards(hand2)
+ value2_1 = []
+ value1_1 = 0
+ value2_2 = []
+ value1_2 = 0
+ for c in count1:
+ if count1[c] == 2:
+ value2_1.append(c)
+ elif count1[c] == 1:
+ value1_1 = c
+ for c in count2:
+ if count2[c] == 2:
+ value2_2.append(c)
+ elif count1[c] == 1:
+ value1_2 = c
+ value2_1.sort()
+ value2_2.sort()
+ if value2_1[1] > value2_2[1]:
+ return 1
+ elif value2_2[1] > value2_1[1]:
+ return 2
+ elif value2_1[0] > value2_2[0]:
+ return 1
+ elif value2_2[0] > value2_1[0]:
+ return 2
+ elif value1_1 > value1_2:
+ return 1
+ else:
+ return 2
+
+ # both are one pair
+ if is_one_pair(hand1):
+ count1 = count_cards(hand1)
+ count2 = count_cards(hand2)
+ value2_1 = 0
+ value1_1 = []
+ value2_2 = 0
+ value1_2 = []
+ for c in count1:
+ if count1[c] == 2:
+ value2_1 = c
+ elif count1[c] == 1:
+ value1_1.append(c)
+ for c in count2:
+ if count2[c] == 2:
+ value2_2 = c
+ elif count2[c] == 1:
+ value1_2.append(c)
+ value1_1.sort()
+ value1_2.sort()
+ if value2_1 > value2_2:
+ return 1
+ elif value2_2 > value2_1:
+ return 2
+ elif high_card(value1_1) > high_card(value1_2):
+ return 1
+ else:
+ return 2
+
+
+ # both are high card
+ if high_card(hand1) > high_card(hand2):
+ return 1
+ else:
+ return 2
+
+
+def rank(hand):
+ if is_royal_flush(hand):
+ return 10
+ if is_straight_flush(hand):
+ return 9
+ if is_four_of_a_kind(hand):
+ return 8
+ if is_full_house(hand):
+ return 7
+ if is_flush(hand):
+ return 6
+ if is_straight(hand):
+ return 5
+ if is_three_of_a_kind(hand):
+ return 4
+ if is_two_pairs(hand):
+ return 3
+ if is_one_pair(hand):
+ return 2
+ return 1 # high card
+
+def winner(hand1, hand2):
+ if rank(hand1) > rank(hand2):
+ return 1
+ if rank(hand2) > rank(hand1):
+ return 2
+ return better_hand(hand1, hand2)
+
+hands = []
+
+f = open('054.txt', 'r')
+for line in f:
+ line.rstrip('\n')
+ hands.append([ handvalue(x) for x in line.split(' ') ])
+f.close()
+
+count_win1 = 0
+
+for h in hands:
+ hand1 = h[:5]
+ hand2 = h[5:]
+ if winner(hand1, hand2) == 1:
+ count_win1 += 1
+
+print count_win1
+
+