···11+import fileinput
22+from collections import Counter
33+44+55+def rank(hand, part_2=False):
66+ # Special-case JJJJJ; other hands Js just become the most common card.
77+ if part_2 and hand != 'JJJJJ':
88+ no_jokers = Counter(c for c in hand if c != 'J').most_common()
99+ hand = hand.replace('J', no_jokers[0][0])
1010+1111+ cmn = Counter(hand).most_common()
1212+1313+ # Five of a Kind
1414+ if cmn[0][1] == 5:
1515+ return 6
1616+1717+ # Four of a Kind
1818+ elif cmn[0][1] == 4:
1919+ return 5
2020+2121+ # Full House / Three of a Kind (based on second-most common card)
2222+ elif cmn[0][1] == 3:
2323+ return 2 + cmn[1][1]
2424+2525+ # Two Pair / One Pair (based on second-most common card)
2626+ elif cmn[0][1] == 2:
2727+ return cmn[1][1]
2828+2929+ return 0
3030+3131+3232+def tiebreak(hand, part_2=False):
3333+ return tuple(card_score(c, part_2) for c in hand)
3434+3535+3636+def card_score(card, part_2=False):
3737+ if part_2:
3838+ return 'J23456789TQKA'.index(card)
3939+ else:
4040+ return '23456789TJQKA'.index(card)
4141+4242+4343+# Parse problem input.
4444+hands = []
4545+for line in fileinput.input():
4646+ hand, bid = line.split()
4747+ hands.append((hand, int(bid)))
4848+4949+5050+# Solve part 1.
5151+part_1 = 0
5252+for i, (hand, bid) in enumerate(sorted(hands, key=lambda h: (rank(h[0]), tiebreak(h[0]))), start=1):
5353+ part_1 += i * bid
5454+5555+print("Part 1:", part_1)
5656+5757+5858+# Solve part 2.
5959+part_2 = 0
6060+for i, (hand, bid) in enumerate(sorted(hands, key=lambda h: (rank(h[0], part_2=True), tiebreak(h[0], part_2=True))), start=1):
6161+ part_2 += i * bid
6262+6363+print("Part 2:", part_2)