--- /dev/null
+#!/usr/bin/env pypy3.10
+
+import sys
+import unittest
+import argparse
+from typing import Sequence
+from enum import IntEnum
+
+class Win(IntEnum):
+ HighCard = 1
+ Pair = 2
+ TwoPair = 3
+ ThreeKind = 4
+ FullHouse = 5
+ FourKind = 6
+ FiveKind = 7
+
+CARDVALUES = {
+ '2': '1',
+ '3': '2',
+ '4': '3',
+ '5': '4',
+ '6': '5',
+ '7': '6',
+ '8': '7',
+ '9': '8',
+ 'T': '9',
+ 'J': 'A',
+ 'Q': 'B',
+ 'K': 'C',
+ 'A': 'D'
+}
+
+def hand_value(hand: str) -> str:
+ return "".join([CARDVALUES[card] for card in hand])
+
+# 5, 4, fh, 3, 2p, p, flush
+def score_hand(s: str) -> Win:
+ hold = {
+ '2': 0, '3': 0, '4': 0, '5': 0, '6': 0, '7': 0, '8': 0,
+ '9': 0, 'T': 0, 'J': 0, 'Q': 0, 'K': 0, 'A': 0
+ }
+ for c in s:
+ hold[c] += 1
+ cards = [item for item in hold.items() if item[1] > 0]
+ cards = sorted(cards, key=lambda x: x[1], reverse=True)
+ if cards[0][1] == 5:
+ win = Win.FiveKind
+ elif cards[0][1] == 4:
+ win = Win.FourKind
+ elif cards[0][1] == 3:
+ if cards[1][1] == 2:
+ win = Win.FullHouse
+ else:
+ win = Win.ThreeKind
+ elif cards[0][1] == 2:
+ if cards[1][1] == 2:
+ win = Win.TwoPair
+ else:
+ win = Win.Pair
+ else:
+ win = Win.HighCard
+ value = int(f"{win.value}" + hand_value(s), 16)
+ return value
+
+def load(filename):
+ with open(filename) as stream:
+ for line in stream:
+ hand, bid = line.strip().split(" ", maxsplit=1)
+ yield hand, bid
+
+def main(args=None):
+ parser = argparse.ArgumentParser(description="advent of code 2023 day 6")
+ parser.add_argument('filename')
+ parser.add_argument('-t', '--test', action='store_true')
+ options = parser.parse_args(args)
+
+ if options.test:
+ return unittest.main()
+
+ total = 0
+ data = [(info[0], info[1], score_hand(info[0])) for info in load(options.filename)]
+ for rank, info in enumerate(sorted(data, key=lambda x: x[2]), 1):
+ hand, bid, score = info
+ print(rank, hand, bid)
+ total += rank * int(bid)
+
+ print(f"part 1: {total}")
+ #print(f"part 2: {part2(options.filename)}")
+
+
+if __name__ == '__main__':
+ sys.exit(main(sys.argv[1:]))