from collections import Counter def read_hands(file_path): """ Reads hands and their bids from the file. Returns a list of tuples (hand, bid). """ try: with open(file_path, "r") as file: return [line.strip().split() for line in file] except Exception as e: print(f"Error reading file {file_path}: {e}") raise def replace_face_cards(hand): """ Replaces face cards with characters that maintain the card order. """ replacements = {"T": "a", "J": "b", "Q": "c", "K": "d", "A": "e"} return "".join(replacements.get(card, card) for card in hand) def categorize_hand(hand): """ Categorizes the hand into its type and returns a tuple of (category, hand). """ hand = replace_face_cards(hand) card_count = Counter(hand) if 5 in card_count.values(): category = 7 elif 4 in card_count.values(): category = 6 elif 3 in card_count.values() and 2 in card_count.values(): category = 5 elif 3 in card_count.values(): category = 4 elif list(card_count.values()).count(2) == 2: category = 3 elif 2 in card_count.values(): category = 2 else: category = 1 return (category, hand) def hand_key(hand): """ Key function for sorting hands. Converts the hand into a format that can be compared directly. """ return categorize_hand(hand[0]) def calculate_total_winnings(file_path): """ Calculates the total winnings from the hands in the file. """ hands = read_hands(file_path) sorted_hands = sorted(hands, key=hand_key, reverse=True) total_winnings = sum( int(bid) * (len(hands) - index) for index, (_, bid) in enumerate(sorted_hands) ) return total_winnings def test(): print("Running test...") try: expected_result = 6440 total_winnings = calculate_total_winnings("../test.txt") assert ( total_winnings == expected_result ), f"Test failed, expected {expected_result} but got {total_winnings}" print(f"Test passed: {total_winnings}") except Exception as e: print(f"Test failed: {e}") def main(): try: test() result = calculate_total_winnings("../input.txt") print(f"Total result from input.txt: {result}") except Exception as e: print(f"An error occurred: {e}") if __name__ == "__main__": main()