from collections import Counter def calculate_rank(hand): card_ranks = {'2': 1, '3': 2, '4': 3, '5': 4, '6': 5, '7': 6, '8': 7, '9': 8, 'T': 9, 'J': 10, 'Q': 11, 'K': 12, 'A': 13} # substitute cards with their ranks hand = sorted(card_ranks.get(c, None) or c for c in hand)[::-1] cnt = Counter(hand) cnt_values = sorted(cnt.values()) rank = { "5": 10, "14": 9, "23": 8, "113": 7, "122": 6, "1112": 5, "11111": 4, }["".join(map(str, cnt_values))] # return rank and sorted hand as a tiebreaker return (rank, hand) def part1(inp): total = 0 hands = [l.strip().split() for l in inp.strip().split("\n")] print(hands[-10: -1]) breakpoint() hands = sorted(hands, key=lambda hb: calculate_rank(hb[0])) for rank, hand in enumerate(hands): hand, bid = hand total += (rank + 1) * int(bid) return total if __name__ == "__main__": sample_input = """ 32T3K 765 T55J5 684 KK677 28 KTJJT 220 QQQJA 483 """ assert part1(sample_input) == 6440 import sys if len(sys.argv) == 2: with open(sys.argv[1]) as f: res = part1(f.read()) print(f"Part 1, res={res}")