aoc2023/d7.py

134 lines
3.1 KiB
Python

import lib
EXAMPLE = """
32T3K 765
T55J5 684
KK677 28
KTJJT 220
QQQJA 483
"""
def rank_hand(hand):
def key_to_int(c):
map = {'A': 14, 'K': 13, 'Q': 12, 'J': 11, 'T': 10}
if c in map:
return map[c]
else:
return ord(c) - 48
suite_to_count = {}
hand = list(map(key_to_int, hand))
for c in hand:
try:
suite_to_count[c] += 1
except:
suite_to_count[c] = 1
freq_to_hand = sorted([(v, k) for (k, v) in suite_to_count.items()], reverse=True)
rank = 0
match freq_to_hand:
case [_, _, _, _, _]:
rank = 0
case [(2, _), (1, _), (1, _), (1, _)]:
rank = 1
case [(2, _), (2, _), (1, _)]:
rank = 2
case [(3, _), (1, _), (1, _)]:
rank = 3
case [(3, _), (2, _)]:
rank = 4
case [(4, _), (1, _)]:
rank = 5
case [(5, _)]:
rank = 6
case _:
print("unexpected hand")
return (rank, hand)
def solve(lines: list[str]):
hands = []
for (i, line) in enumerate(lines):
hand, value = line.split()
hands.append((hand, value))
res = 0
hands = sorted(hands, key=lambda h: rank_hand(h[0]))
for i, (hand, value) in enumerate(hands):
v = (i + 1) * int(value)
res += v
return res
def rank_hand2(hand):
orig = str(hand)
def key_to_int(c):
map = {'A': 14, 'K': 13, 'Q': 12, 'T': 10, 'J': 0}
if c in map:
return map[c]
else:
return ord(c) - 48
j_count = hand.count("J")
suite_to_count = {}
hand = list(map(key_to_int, hand))
for c in hand:
if c == 0:
continue
try:
suite_to_count[c] += 1
except:
suite_to_count[c] = 1
rank = 0
freqs = list(sorted(suite_to_count.values(), reverse=True))
if freqs:
freqs[0] += j_count
else:
freqs = [j_count]
rank = 0
match freqs:
case [_, _, _, _, _]:
rank = 0
case [2, 2, _]:
rank = 2
case [2, _, _, _]:
rank = 1
case [3, 2]:
rank = 4
case [3, _, _]:
rank = 3
case [4, _]:
rank = 5
case [5]:
rank = 6
case h:
print("unexpected hand", h, orig)
return (rank, hand)
def solve2(lines: list[str]):
hands = []
for (i, line) in enumerate(lines):
hand, value = line.split()
hands.append((hand, value))
res = 0
hands = sorted(hands, key=lambda h: rank_hand2(h[0]))
for i, (hand, value) in enumerate(hands):
v = (i + 1) * int(value)
res += v
return res
def main():
lines = lib.str_to_lines_no_empty(EXAMPLE)
print("Example 1:", solve(lines))
lines = lib.str_to_lines_no_empty(open("i7.txt").read())
print("Solution 1:", solve(lines))
lines = lib.str_to_lines_no_empty(EXAMPLE)
print("Example 2:", solve2(lines))
lines = lib.str_to_lines_no_empty(open("i7.txt").read())
print("Solution 2:", solve2(lines))
if __name__ == "__main__":
main()