From 6b0928e4b7e6ff915a5c46a5b71973b03d53b0d1 Mon Sep 17 00:00:00 2001 From: Christoph Stahl Date: Thu, 7 Dec 2023 10:01:26 +0100 Subject: [PATCH] crude day07 --- aoc/day07.py | 124 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 124 insertions(+) create mode 100644 aoc/day07.py diff --git a/aoc/day07.py b/aoc/day07.py new file mode 100644 index 0000000..82a8867 --- /dev/null +++ b/aoc/day07.py @@ -0,0 +1,124 @@ +from __future__ import annotations + +from enum import Enum +from collections import defaultdict +from functools import reduce + +from .aoc import AocParseLinesSameParser, Aoc2 + + +class Type(Enum): + HIGH_CARD = 0 + ONE_PAIR = 1 + TWO_PAIR = 2 + THREE_KIND = 3 + FULL_HOUSE = 4 + FOUR_KIND = 5 + FIVE_KIND = 6 + + def __lt__(self, other: Type) -> bool: + return self.value < other.value + +class Hand2: + def __init__(self, string: str) -> None: + translation = "J23456789TQKA" + self.string = [translation.index(x) for x in string] + self.cards_dict = defaultdict(lambda : 0) + for letter in string: + self.cards_dict[letter] += 1 + + value_amount = list(reversed(sorted(list([v for k, v in self.cards_dict.items() if k !="J"])))) + joker_amount = self.cards_dict["J"] + + if joker_amount == 5: + self.type = Type.FIVE_KIND + return + + match value_amount[0] + joker_amount: + case 5: + self.type = Type.FIVE_KIND + case 4: + self.type = Type.FOUR_KIND + case 3: + if value_amount[1] == 2: + self.type = Type.FULL_HOUSE + else: + self.type = Type.THREE_KIND + case 2: + if value_amount[1] == 2: + self.type = Type.TWO_PAIR + else: + self.type = Type.ONE_PAIR + case _: + self.type = Type.HIGH_CARD + + + + def __lt__(self, other: Hand) -> bool: + """ self < other """ + return (self.type, self.string) < (other.type, other.string) + + def __repr__(self) -> str: + return f"Hand({self.type}, {self.string})" + +class Hand: + def __init__(self, string: str) -> None: + translation = "23456789TJQKA" + self.string = [translation.index(x) for x in string] + self.cards_dict = defaultdict(lambda : 0) + for letter in string: + self.cards_dict[letter] += 1 + + value_amount = list(reversed(sorted(list(self.cards_dict.values())))) + + match value_amount[0]: + case 5: + self.type = Type.FIVE_KIND + case 4: + self.type = Type.FOUR_KIND + case 3: + if value_amount[1] == 2: + self.type = Type.FULL_HOUSE + else: + self.type = Type.THREE_KIND + case 2: + if value_amount[1] == 2: + self.type = Type.TWO_PAIR + else: + self.type = Type.ONE_PAIR + case _: + self.type = Type.HIGH_CARD + + + + def __lt__(self, other: Hand) -> bool: + """ self < other """ + return (self.type, self.string) < (other.type, other.string) + + def __repr__(self) -> str: + return f"Hand({self.type}, {self.string})" + + +# class Day07(AocParseLinesSameParser[tuple[Hand, int]], Aoc2[list[tuple[Hand, int]], list[tuple[Hand, int]]]): +class Day07(Aoc2[list[tuple[Hand, int]], list[tuple[Hand2, int]]]): + def parseinput1(self, inpt: str) -> list[tuple[Hand, int]]: + lines = inpt.splitlines() + return [(Hand(line.split(" ")[0]), int(line.split(" ")[1])) for line in lines] + + def parseinput2(self, inpt: str) -> list[tuple[Hand2, int]]: + lines = inpt.splitlines() + return [(Hand2(line.split(" ")[0]), int(line.split(" ")[1])) for line in lines] + + def part1(self, inpt: list[tuple[Hand, int]]) -> int: + return sum(((rnk + 1) * bid) for rnk, (_, bid) in list(enumerate(sorted(inpt)))) + + def part2(self, inpt: list[tuple[Hand2, int]]) -> int: + return sum(((rnk + 1) * bid) for rnk, (_, bid) in list(enumerate(sorted(inpt)))) + +def main() -> None: + day07 = Day07(2023, 7) + day07.run() + +if __name__ == "__main__": + main() +