0xtao

Finished
1def best_hands(hands: list[str]) -> list[str]: # each hand is a string like "4S 5S 7H 8D JC"
2 pass
1def best_hands(hands: list[str]) -> list[str]:
2 """
3 Determine the best poker hand(s) from a list of poker hands.
4
5 Args:
6 hands: List of strings, each representing a poker hand with 5 cards
7
8 Returns:
9 List of strings representing the best hand(s)
10 """
11 if not hands:
12 return []
13
14 # Edge Case: Single hand provided
15 if len(hands) == 1:
16 return hands
17
18 ranked_hands = []
19 for hand in hands:
20 ranked_hands.append((hand, rank_hand(hand)))
21
22 # Find the maximum rank
23 max_rank = max(rank for _, rank in ranked_hands)
24
25 # Filter hands with maximum rank
26 best_hands_list = [hand for hand, rank in ranked_hands if rank == max_rank]
27
28 return best_hands_list
29
30
31def rank_hand(hand: str) -> tuple:
32 """
33 Rank a poker hand according to its strength.
34
35 Returns a tuple where the first element is the hand rank (higher is better)
36 and subsequent elements are tie-breakers.
37 """
38 cards = hand.split()
39
40 # Edge Case: Invalid hand format
41 if len(cards) != 5:
42 raise ValueError("Each hand must contain exactly 5 cards")
43
44 values = []
45 suits = []
46
47 for card in cards:
48 # Edge Case: Invalid card format
49 if len(card) < 2 or len(card) > 3:
50 raise ValueError(f"Invalid card format: {card}")
51
52 value = card[:-1]
53 suit = card[-1]
54
55 # Edge Case: Invalid suit
56 if suit not in 'SHDC':
57 raise ValueError(f"Invalid suit: {suit}")
58
59 # Convert face cards to numbers
60 if value == 'A':
61 numeric_value = 14
62 elif value == 'K':
63 numeric_value = 13
64 elif value == 'Q':
65 numeric_value = 12
66 elif value == 'J':
67 numeric_value = 11
68 else:
69 try:
70 numeric_value = int(value)
71 # Edge Case: Invalid card value
72 if numeric_value < 2 or numeric_value > 10:
73 raise ValueError(f"Invalid card value: {value}")
74 except ValueError:
75 raise ValueError(f"Invalid card value: {value}")
76
77 values.append(numeric_value)
78 suits.append(suit)
79
80 # Sort values for easier comparison
81 values.sort()
82
83 # Check for flush (all cards same suit)
84 is_flush = len(set(suits)) == 1
85
86 # Check for straight
87 is_straight = False
88 # Special case: Ace-low straight (A,2,3,4,5)
89 if values == [2, 3, 4, 5, 14]:
90 is_straight = True
91 # For tie-breaking, treat Ace as 1 in this case
92 values = [1, 2, 3, 4, 5]
93 # Normal straight
94 elif all(values[i] + 1 == values[i+1] for i in range(4)):
95 is_straight = True
96
97 # Count occurrences of each value
98 value_counts = {}
99 for value in values:
100 value_counts[value] = value_counts.get(value, 0) + 1
101
102 counts = sorted(value_counts.values(), reverse=True)
103
104 # Determine hand rank
105 if is_straight and is_flush:
106 # Straight flush
107 return (8, values[-1]) # Rank 8, high card for tie-break
108 elif 4 in counts:
109 # Four of a kind
110 four_kind_value = [v for v, count in value_counts.items() if count == 4][0]
111 other_value = [v for v, count in value_counts.items() if count == 1][0]
112 return (7, four_kind_value, other_value) # Rank 7, four of a kind value, kicker
113 elif 3 in counts and 2 in counts:
114 # Full house
115 three_kind_value = [v for v, count in value_counts.items() if count == 3][0]
116 pair_value = [v for v, count in value_counts.items() if count == 2][0]
117 return (6, three_kind_value, pair_value) # Rank 6, three of a kind value, pair value
118 elif is_flush:
119 # Flush
120 return (5, values[4], values[3], values[2], values[1], values[0]) # Rank 5, sorted values for tie-break
121 elif is_straight:
122 # Straight
123 return (4, values[-1]) # Rank 4, high card for tie-break
124 elif 3 in counts:
125 # Three of a kind
126 three_kind_value = [v for v, count in value_counts.items() if count == 3][0]
127 other_values = sorted([v for v, count in value_counts.items() if count == 1], reverse=True)
128 return (3, three_kind_value, other_values[0], other_values[1]) # Rank 3, three of a kind value, kickers
129 elif counts.count(2) == 2:
130 # Two pair
131 pair_values = sorted([v for v, count in value_counts.items() if count == 2], reverse=True)
132 other_value = [v for v, count in value_counts.items() if count == 1][0]
133 return (2, pair_values[0], pair_values[1], other_value) # Rank 2, pair values, kicker
134 elif 2 in counts:
135 # One pair
136 pair_value = [v for v, count in value_counts.items() if count == 2][0]
137 other_values = sorted([v for v, count in value_counts.items() if count == 1], reverse=True)
138 return (1, pair_value, other_values[0], other_values[1], other_values[2]) # Rank 1, pair value, kickers
139 else:
140 # High card
141 return (0, values[4], values[3], values[2], values[1], values[0]) # Rank 0, sorted values for tie-break
142
143# Handled Edge Cases: Empty hands list, single hand, invalid hand format (not 5 cards), invalid card format, invalid suit, invalid card value, ace-low straight
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.