Skip to content

Instantly share code, notes, and snippets.

@rochacbruno
Created May 26, 2020 17:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rochacbruno/43b8204ec5d672238afc6d1f5a50de8a to your computer and use it in GitHub Desktop.
Save rochacbruno/43b8204ec5d672238afc6d1f5a50de8a to your computer and use it in GitHub Desktop.
"""
Poker Ranker for Exercism.io
"""
def best_hands(hands):
hands = serialize(hands)
return [
deserialize(hand)
for hand in hands
if card_ranks(hand) == card_ranks(max(hands, key=hand_rank))
]
def serialize(hands):
"""["10C AH"] -> [("0", "C"), ("A", "H"),]"""
_hands = []
for hand in hands:
_hand = []
for card in hand.split():
_hand.append((card[-2], card[-1]))
_hands.append(_hand)
return _hands
def deserialize(hand):
"""[("0", "C"), ("A", "H"),] -> ["10C AH"]"""
return " ".join(["".join(["10" if r == "0" else r, s]) for r, s in hand])
def hand_rank(hand):
"""takes serialized hands and resturns its ranking"""
ranks = card_ranks(hand)
groups = [(ranks.count(i), i) for i in set(ranks)]
groups.sort(reverse=True)
counts, number = zip(*groups)
straight = (len(counts) == 5) and (max(number) - min(number) == 4)
flush = len(set([s for r, s in hand])) == 1
return (
8 if straight and flush else
7 if counts == (4, 1) else
6 if counts == (3, 2) else
5 if flush else
4 if straight else
3 if counts == (3, 1, 1) else
2 if counts == (2, 2, 1) else
1 if counts == (2, 1, 1, 1) else
0, number
)
def card_ranks(hand):
ranks = ["--234567890JQKA".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
# ------------ TESTS ------------
def test_single_hand_always_wins():
hands = ["4S 5S 7H 8D JC"]
expected = ["4S 5S 7H 8D JC"]
assert best_hands(hands) == expected
def test_highest_card_out_of_all_hands_wins():
hands = [
"4D 5S 6S 8D 3C",
"2S 4C 7S 9H 10H",
"3S 4S 5D 6H JH",
]
expected = ["3S 4S 5D 6H JH"]
assert best_hands(hands) == expected
def test_tie_has_multiple_winners():
hands = [
"4D 5S 6S 8D 3C",
"2S 4C 7S 9H 10H",
"3S 4S 5D 6H JH",
"3H 4H 5C 6C JD",
]
expected = [
"3S 4S 5D 6H JH",
"3H 4H 5C 6C JD",
]
assert best_hands(hands) == expected
def test_tie_compares_multiple():
hands = [
"3S 5H 6S 8D 7H",
"2S 5D 6D 8C 7S",
]
expected = ["3S 5H 6S 8D 7H"]
assert best_hands(hands) == expected
def test_one_pair_beats_high_card():
hands = [
"4S 5H 6C 8D KH",
"2S 4H 6S 4D JH",
]
expected = ["2S 4H 6S 4D JH"]
assert best_hands(hands) == expected
def test_highest_pair_wins():
hands = [
"4S 2H 6S 2D JH",
"2S 4H 6C 4D JD",
]
expected = ["2S 4H 6C 4D JD"]
assert best_hands(hands) == expected
def test_two_pairs_beats_one_pair():
hands = [
"2S 8H 6S 8D JH",
"4S 5H 4C 8C 5C",
]
expected = ["4S 5H 4C 8C 5C"]
assert best_hands(hands) == expected
def test_two_double_pair():
hands = [
"2S 8H 2D 8D 3H",
"4S 5H 4C 8S 5D",
]
expected = ["2S 8H 2D 8D 3H"]
assert best_hands(hands) == expected
def test_two_double_pair_higher_tie():
hands = [
"2S QS 2C QD JH",
"JD QH JS 8D QC",
]
expected = ["JD QH JS 8D QC"]
assert best_hands(hands) == expected
def test_two_double_pair_tie_kicker():
hands = [
"JD QH JS 8D QC",
"JS QS JC 2D QD",
]
expected = ["JD QH JS 8D QC"]
assert best_hands(hands) == expected
def test_three_of_a_kind_beats_two_pair():
hands = [
"2S 8H 2H 8D JH",
"4S 5H 4C 8S 4H",
]
expected = ["4S 5H 4C 8S 4H"]
assert best_hands(hands) == expected
def test_two_triple_pair():
hands = [
"2S 2H 2C 8D JH",
"4S AH AS 8C AD",
]
expected = ["4S AH AS 8C AD"]
assert best_hands(hands) == expected
def test_two_three_multiple_decks():
hands = [
"4S AH AS 7C AD",
"4S AH AS 8C AD",
]
expected = ["4S AH AS 8C AD"]
assert best_hands(hands) == expected
def test_three_vs_straight():
hands = [
"4S 5H 4C 8D 4H",
"3S 4D 2S 6D 5C",
]
expected = ["3S 4D 2S 6D 5C"]
assert best_hands(hands) == expected
def test_aces_can_end_straight():
hands = [
"4S 5H 4C 8D 4H",
"10D JH QS KD AC",
]
expected = ["10D JH QS KD AC"]
assert best_hands(hands) == expected
def test_aces_can_start_straight():
hands = [
"4S 5H 4C 8D 4H",
"4D AH 3S 2D 5C",
]
expected = ["4D AH 3S 2D 5C"]
assert best_hands(hands) == expected
def test_two_straights():
hands = [
"4S 6C 7S 8D 5H",
"5S 7H 8S 9D 6H",
]
expected = ["5S 7H 8S 9D 6H"]
assert best_hands(hands) == expected
def test_lowest_straight():
hands = [
"2H 3C 4D 5D 6H",
"4S AH 3S 2D 5H",
]
expected = ["2H 3C 4D 5D 6H"]
assert best_hands(hands) == expected
def test_straight_vs_flush():
hands = [
"4C 6H 7D 8D 5H",
"2S 4S 5S 6S 7S",
]
expected = ["2S 4S 5S 6S 7S"]
assert best_hands(hands) == expected
def test_two_flushes():
hands = [
"4H 7H 8H 9H 6H",
"2S 4S 5S 6S 7S",
]
expected = ["4H 7H 8H 9H 6H"]
assert best_hands(hands) == expected
def test_flush_vs_full():
hands = [
"3H 6H 7H 8H 5H",
"4S 5H 4C 5D 4H",
]
expected = ["4S 5H 4C 5D 4H"]
assert best_hands(hands) == expected
def test_two_fulls():
hands = [
"4H 4S 4D 9S 9D",
"5H 5S 5D 8S 8D",
]
expected = ["5H 5S 5D 8S 8D"]
assert best_hands(hands) == expected
def test_two_fulls_same_triplet():
hands = [
"5H 5S 5D 9S 9D",
"5H 5S 5D 8S 8D",
]
expected = ["5H 5S 5D 9S 9D"]
assert best_hands(hands) == expected
def test_full_vs_four():
hands = [
"4S 5H 4D 5D 4H",
"3S 3H 2S 3D 3C",
]
expected = ["3S 3H 2S 3D 3C"]
assert best_hands(hands) == expected
def test_two_fours():
hands = [
"2S 2H 2C 8D 2D",
"4S 5H 5S 5D 5C",
]
expected = ["4S 5H 5S 5D 5C"]
assert best_hands(hands) == expected
def test_two_fours_kicker():
hands = [
"3S 3H 2S 3D 3C",
"3S 3H 4S 3D 3C",
]
expected = ["3S 3H 4S 3D 3C"]
assert best_hands(hands) == expected
def test_four_vs_straight_flush():
hands = [
"4S 5H 5S 5D 5C",
"7S 8S 9S 6S 10S",
]
expected = ["7S 8S 9S 6S 10S"]
assert best_hands(hands) == expected
def test_two_straight_flushes():
hands = [
"4H 6H 7H 8H 5H",
"5S 7S 8S 9S 6S",
]
expected = ["5S 7S 8S 9S 6S"]
assert best_hands(hands) == expected
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment