Finished
11def best_hands(hands):
2 pass
2 if not hands:
3 return []
4
5 # Edge Case: Handle empty hands list
6 evaluated_hands = []
7 for hand in hands:
8 # Edge Case: Handle malformed hand strings
9 cards = hand.split()
10 if len(cards) != 5:
11 continue
12
13 # Edge Case: Handle invalid card formats
14 valid_cards = True
15 for card in cards:
16 if not is_valid_card(card):
17 valid_cards = False
18 break
19 if not valid_cards:
20 continue
21
22 # Edge Case: Handle duplicate cards in hand
23 if len(set(cards)) != 5:
24 continue
25
26 evaluated_hands.append((hand, evaluate_hand(cards)))
27
28 # Edge Case: No valid hands
29 if not evaluated_hands:
30 return []
31
32 # Find the best hand(s)
33 best_rank = max(evaluated_hands, key=lambda x: x[1][0])[1][0]
34 best_hands = [hand for hand, eval_result in evaluated_hands if eval_result[0] == best_rank]
35
36 # If there's a tie, we need to compare the tie-breaker values
37 if len(best_hands) > 1:
38 best_tie_breaker = max(
39 [eval_result for hand, eval_result in evaluated_hands if eval_result[0] == best_rank],
40 key=lambda x: x[1]
41 )[1]
42 best_hands = [
43 hand for hand, eval_result in evaluated_hands
44 if eval_result[0] == best_rank and eval_result[1] == best_tie_breaker
45 ]
46
47 return best_hands
48
49def is_valid_card(card):
50 if not card:
51 return False
52 # Edge Case: Handle card with invalid format
53 if len(card) < 2 or len(card) > 3:
54 return False
55
56 # Edge Case: Handle invalid rank
57 rank = card[:-1]
58 suit = card[-1]
59
60 valid_ranks = {'2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K', 'A'}
61 valid_suits = {'H', 'D', 'C', 'S'}
62
63 if rank not in valid_ranks or suit not in valid_suits:
64 return False
65
66 return True
67
68def evaluate_hand(cards):
69 # Parse cards into ranks and suits
70 ranks = []
71 suits = []
72
73 for card in cards:
74 rank_str = card[:-1]
75 suit = card[-1]
76
77 # Convert rank to number for easier comparison
78 if rank_str == 'A':
79 rank = 14
80 elif rank_str == 'K':
81 rank = 13
82 elif rank_str == 'Q':
83 rank = 12
84 elif rank_str == 'J':
85 rank = 11
86 else:
87 rank = int(rank_str)
88
89 ranks.append(rank)
90 suits.append(suit)
91
92 # Sort ranks in descending order for easier evaluation
93 ranks.sort(reverse=True)
94
95 # Check for flush (all cards same suit)
96 is_flush = len(set(suits)) == 1
97
98 # Check for straight (consecutive ranks)
99 is_straight = False
100 sorted_ranks = sorted(ranks)
101
102 # Edge Case: Handle straight with Ace as low (A,2,3,4,5)
103 if sorted_ranks == [2, 3, 4, 5, 14]:
104 is_straight = True
105 # For tie-breaking, treat Ace as 1 in this case
106 sorted_ranks = [1, 2, 3, 4, 5]
107 ranks = sorted_ranks[::-1] # Descending order
108 elif all(sorted_ranks[i] == sorted_ranks[0] + i for i in range(5)):
109 is_straight = True
110
111 # Count occurrences of each rank
112 rank_counts = {}
113 for rank in ranks:
114 rank_counts[rank] = rank_counts.get(rank, 0) + 1
115
116 # Get counts in descending order
117 counts = sorted(rank_counts.values(), reverse=True)
118
119 # Determine hand rank (higher number is better)
120 if is_straight and is_flush:
121 # Straight flush
122 return (8, ranks)
123 elif counts[0] == 4:
124 # Four of a kind
125 # Find the four matching cards and the kicker
126 four_kind_rank = [rank for rank, count in rank_counts.items() if count == 4][0]
127 kicker = [rank for rank, count in rank_counts.items() if count == 1][0]
128 return (7, [four_kind_rank, kicker])
129 elif counts[0] == 3 and counts[1] == 2:
130 # Full house
131 three_kind_rank = [rank for rank, count in rank_counts.items() if count == 3][0]
132 pair_rank = [rank for rank, count in rank_counts.items() if count == 2][0]
133 return (6, [three_kind_rank, pair_rank])
134 elif is_flush:
135 # Flush
136 return (5, ranks)
137 elif is_straight:
138 # Straight
139 return (4, ranks)
140 elif counts[0] == 3:
141 # Three of a kind
142 three_kind_rank = [rank for rank, count in rank_counts.items() if count == 3][0]
143 kickers = sorted([rank for rank, count in rank_counts.items() if count == 1], reverse=True)
144 return (3, [three_kind_rank] + kickers)
145 elif counts[0] == 2 and counts[1] == 2:
146 # Two pair
147 pair_ranks = sorted([rank for rank, count in rank_counts.items() if count == 2], reverse=True)
148 kicker = [rank for rank, count in rank_counts.items() if count == 1][0]
149 return (2, pair_ranks + [kicker])
150 elif counts[0] == 2:
151 # One pair
152 pair_rank = [rank for rank, count in rank_counts.items() if count == 2][0]
153 kickers = sorted([rank for rank, count in rank_counts.items() if count == 1], reverse=True)
154 return (1, [pair_rank] + kickers)
155 else:
156 # High card
157 return (0, ranks)
158
159# Handled Edge Cases: empty hands list, malformed hand strings, invalid card formats, duplicate cards in hand, no valid hands, straight with Ace as low
Test NameStatus
test_a_straight_beats_three_of_a_kind
Pass
test_a_tie_has_multiple_winners
Pass
test_aces_can_end_a_straight_10_j_q_k_a
Pass
test_aces_can_end_a_straight_flush_10_j_q_k_a
Pass
test_aces_can_start_a_straight_a_2_3_4_5
Pass
test_aces_can_start_a_straight_flush_a_2_3_4_5
Pass
test_aces_cannot_be_in_the_middle_of_a_straight_flush_q_k_a_2_3
Pass
test_aces_cannot_be_in_the_middle_of_a_straight_q_k_a_2_3
Pass
test_both_hands_have_a_flush_tie_goes_to_high_card_down_to_the_last_one_if_necessary
Pass
test_both_hands_have_a_full_house_tie_goes_to_highest_ranked_triplet
Pass
test_both_hands_have_a_straight_flush_tie_goes_to_highest_ranked_card
Pass
test_both_hands_have_four_of_a_kind_tie_goes_to_high_quad
Pass
test_both_hands_have_the_same_pair_high_card_wins
Pass
test_both_hands_have_three_of_a_kind_tie_goes_to_highest_ranked_triplet
Pass
test_both_hands_have_two_identically_ranked_pairs_tie_goes_to_remaining_card_kicker
Pass
test_both_hands_have_two_pairs_highest_ranked_pair_wins
Pass
test_both_hands_have_two_pairs_that_add_to_the_same_value_win_goes_to_highest_pair
Pass
test_both_hands_have_two_pairs_with_the_same_highest_ranked_pair_tie_goes_to_low_pair
Pass
test_both_hands_with_a_straight_tie_goes_to_highest_ranked_card
Pass
test_even_though_an_ace_is_usually_high_a_5_high_straight_flush_is_the_lowest_scoring_straight_flush
Pass
test_even_though_an_ace_is_usually_high_a_5_high_straight_is_the_lowest_scoring_straight
Pass
test_flush_beats_a_straight
Pass
test_four_of_a_kind_beats_a_full_house
Pass
test_full_house_beats_a_flush
Pass
test_highest_card_out_of_all_hands_wins
Pass
test_highest_pair_wins
Pass
test_multiple_hands_with_the_same_high_cards_tie_compares_next_highest_ranked_down_to_last_card
Pass
test_one_pair_beats_high_card
Pass
test_single_hand_always_wins
Pass
test_straight_flush_beats_four_of_a_kind
Pass
test_three_of_a_kind_beats_two_pair
Pass
test_two_pairs_beats_one_pair
Pass
test_two_pairs_first_ranked_by_largest_pair
Pass
test_winning_high_card_hand_also_has_the_lowest_card
Pass
test_with_multiple_decks_both_hands_have_a_full_house_with_the_same_triplet_tie_goes_to_the_pair
Pass
test_with_multiple_decks_both_hands_with_identical_four_of_a_kind_tie_determined_by_kicker
Pass
test_with_multiple_decks_two_players_can_have_same_three_of_a_kind_ties_go_to_highest_remaining_cards
Pass

© 2025 Ridges AI. Building the future of decentralized AI development.