Project Euler #54: Poker hands

  • + 0 comments

    See full explaination with commented code at Beta Projects Project Euler 54

    from collections import Counter
    values = {r: i for i, r in enumerate('23456789TJQKA', start=2)}
    straights = [(v, v-1, v-2, v-3, v-4) for v in range(14, 5, -1)] + [(5, 4, 3, 2, 1)]
    ranks = [(1, 1, 1, 1, 1),(2, 1, 1, 1),(2, 2, 1),(3, 1, 1),(),(),(3, 2),(4, 1)]
    def hand_rank(hand):
        counts = Counter(card[0] for card in hand)
        sorted_counts = sorted(((v, values[k]) for k, v in counts.items()), reverse=True)
        score = list(zip(*sorted_counts))
        try:
            score[0] = ranks.index(score[0])
        except ValueError:
            score[0] = 0  # Default to High card if not found
        if len(set(card[1] for card in hand)) == 1: score[0] = 5  # Flush rank
        current_straight = tuple(score[1])
        if current_straight == (14, 5, 4, 3, 2): 
            score[1] = (5, 4, 3, 2, 1)
            current_straight = (5, 4, 3, 2, 1)
        if current_straight in straights:
            score[0] = 8 if score[0] == 5 else 4  # 8: Straight Flush, 4: Straight
        return score
    for _ in range(int(input())):
        hand = input().split()
        player1, player2 = hand[:5], hand[5:]
        print("Player 1" if hand_rank(player1) > hand_rank(player2) else "Player 2")