#!/usr/bin/env python3 from collections import Counter from enum import IntEnum, auto order = 'J23456789TQKA' class Hand(IntEnum): HighCard = auto() OnePair = auto() TwoPair = auto() ThreeKind = auto() FullHouse = auto() FourKind = auto() FiveKind = auto() def rank_card(card): return order.find(card) def evaluate(cards): co = Counter(cards) common = co.most_common() ret = None if len(common) == 5: if 'J' not in cards: ret = Hand.HighCard # A2345 else: ret = Hand.OnePair # JA234 elif len(common) == 4: if 'J' not in cards: ret = Hand.OnePair # AA234 else: ret = Hand.ThreeKind # JAA23 or JJA23 elif len(common) == 3: if 'J' not in cards: if common[0][1] == 3: if common[1][1] == 2: ret = Hand.FullHouse # AAA22 else: ret = Hand.ThreeKind # AAA23 elif common[0][1] == common[1][1]: ret = Hand.TwoPair # AA223 else: if common[0][1] == 3: # JJJ23 or 222J3 ret = Hand.FourKind elif common[1][1] == 2 and common[2][0] != 'J': ret = Hand.FourKind # JJ223 or 22JJ3 else: # 2233J ret = Hand.FullHouse elif len(common) == 2: if 'J' not in cards: if common[0][1] == 4: ret = Hand.FourKind else: ret = Hand.FullHouse else: # JJJ22 or JJJJ2 ret = Hand.FiveKind else: ret = Hand.FiveKind ret = [int(ret)] ret.extend([rank_card(card) for card in cards]) return tuple(ret) def rank_hand(hand): return evaluate(hand) hands = {} bids = {} value = {} with open('input.txt', mode='r') as f: for line in f.readlines(): line = line[:-1] hand, bid = line.split(' ', maxsplit=1) bid = int(bid) hands[hand] = hand bids[hand] = bid value[rank_hand(hand)] = hand ranks = list(value.keys()) ranks.sort() ranking = {k: ranks.index(k) + 1 for k in value.keys()} winnings = {k: bids[k] * ranking[v] for v, k in value.items()} for i in range(len(ranks)): hand = value[ranks[i]] print('hand', hand, 'is rank', i + 1, '=', ranks[i], f'bidding {bids[hand]}, and wins', winnings[hand]) print(sum(winnings.values()))