From f29447c18bd42202930e57cd879a4b6109d8426c Mon Sep 17 00:00:00 2001 From: felixm Date: Thu, 7 Dec 2023 23:57:38 -0500 Subject: [PATCH] Do day 7. --- .gitignore | 1 + README.md | 3 +- d7.py | 133 +++++++++++++++++++++++++++++++++++++++++++++++++++++ dx.py | 29 +++++------- lib.py | 18 ++++++++ 5 files changed, 165 insertions(+), 19 deletions(-) create mode 100644 .gitignore create mode 100644 d7.py create mode 100644 lib.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..bee8a64 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +__pycache__ diff --git a/README.md b/README.md index b308099..ad7887d 100644 --- a/README.md +++ b/README.md @@ -6,4 +6,5 @@ - Day 4: 1st 9:06, 2nd 22:31; it wasn't hard but I didn't think quick enough :/ - Day 5: 1st 25:00, 2nd 1:55:00; Required patience and accuracy - Day 6: 13:54; I was slow because I thought it is much harder? -- Day 7: +- Day 7: 75:00; leaderboard 16:00... that was just bad; no excuse +- Day 8: diff --git a/d7.py b/d7.py new file mode 100644 index 0000000..932c7d0 --- /dev/null +++ b/d7.py @@ -0,0 +1,133 @@ +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() diff --git a/dx.py b/dx.py index af29049..61e8a65 100644 --- a/dx.py +++ b/dx.py @@ -1,20 +1,14 @@ -from string import ascii_lowercase, ascii_uppercase, digits -import re +import lib EXAMPLE = """ """ -def str_to_int_lst(s): - return list(map(int, s.split())) - -def clean(text: str) -> list[str]: - return list(filter(lambda l: l.strip() != "", text.splitlines())) - # return list(text.splitlines()) - def solve(lines: list[str]): res = 0 for (i, line) in enumerate(lines): print(i, line) + # digits = lib.str_to_int_list(line) + # digit = lib.str_to_single_int(line) return res def solve2(lines: list[str]): @@ -24,21 +18,20 @@ def solve2(lines: list[str]): return res def main(): - example = clean(EXAMPLE) - print("Example 1:", solve(example)) + lines = lib.str_to_lines_no_empty(EXAMPLE) + print("Example 1:", solve(lines)) return - data = clean(open("i5.txt").read()) - print("Solution 1:", solve(data)) + lines = lib.str_to_lines_no_empty(open("ix.txt").read()) + print("Solution 1:", solve(lines)) return - example = clean(EXAMPLE) - print("Example 2:", solve2(example)) + lines = lib.str_to_lines_no_empty(EXAMPLE) + print("Example 2:", solve2(lines)) return - data = clean(open("i5.txt").read()) - print("Solution 2:", solve2(data)) - return + lines = lib.str_to_lines_no_empty(open("ix.txt").read()) + print("Solution 2:", solve2(lines)) if __name__ == "__main__": main() diff --git a/lib.py b/lib.py new file mode 100644 index 0000000..6e4715b --- /dev/null +++ b/lib.py @@ -0,0 +1,18 @@ +import re + +def str_to_single_int(line: str) -> int: + line = line.replace(" ", "") + r = re.compile(r"\d+") + for m in r.findall(line): + return int(m) + raise Exception("No single digit sequence in '{line}'") + +def str_to_int_list(line: str) -> list[int]: + r = re.compile(r"\d+") + return list(map(int, r.findall(line))) + +def str_to_lines_no_empty(text: str) -> list[str]: + return list(filter(lambda l: l.strip() != "", text.splitlines())) + +def str_to_lines(text: str) -> list[str]: + return list(text.splitlines())