Skip to content

Commit

Permalink
Merge pull request #237 from Stegallo/2023
Browse files Browse the repository at this point in the history
2023
  • Loading branch information
Stegallo authored Dec 15, 2023
2 parents fdb5d28 + fd34717 commit 452e5fa
Show file tree
Hide file tree
Showing 4 changed files with 280 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .sourcery.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
rule_settings:
disable: [reintroduce-else]
63 changes: 63 additions & 0 deletions tests/y_2023/test_2023_day7.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
from __future__ import annotations

from unittest.mock import mock_open, patch

from y_2023.day7 import Day, Hand

with patch("builtins.open", mock_open(read_data="0 1")):
day = Day()


def test_Hand():
print()
h = Hand("32T3K")
h = Hand("3333K")
print(h)
print(h.rate("original"))


def test_Hand_five():
h = Hand("AAAAA")
assert h.rate("original") == ("Five of a kind") # , "A")


def test_Hand_four():
h = Hand("AA8AA")
assert h.rate("original") == ("Four of a kind") # , "A")


def test_Hand_full():
h = Hand("23332")
assert h.rate("original") == ("Full house") # , "3", "2")


def test_Hand_three():
h = Hand("AA8A9")
assert h.rate("original") == ("Three of a kind") # , "A")


def test_Hand_two_pair():
h = Hand("AA898")
assert h.rate("original") == ("Two pair") # , "A", "8")


def test_Hand_one_pair():
h = Hand("AA8J9")
assert h.rate("original") == ("One pair") # , "A")


def test_Hand_high_card():
h = Hand("23456")
assert h.rate("original") == ("High card") # , None)


def test__preprocess_input():
pass


def test_calculate_1():
pass


def test_calculate_2():
pass
62 changes: 62 additions & 0 deletions y_2023/day6.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
from common.aoc import AoCDay
from typing import List, Optional
from pydantic.dataclasses import dataclass


@dataclass
class Placeholder:
name: str
orig_sequence: str
sequence: Optional[List[int]] = None
sequence_kernig: Optional[int] = None

def __post_init__(self) -> None:
self.sequence = [int(i) for i in self.orig_sequence.split()]
self.sequence_kernig = int(self.orig_sequence.replace(" ", ""))

@property
def size(self):
return len(self.sequence)


class Time(Placeholder):
...


class Distance(Placeholder):
...


class Day(AoCDay):
def __init__(self, test=0):
super().__init__(__name__, test)

def _preprocess_input(self):
self.__input_data = self._input_data[0]

def _calculate_1(self) -> int: # 227850
time = Time(*self.__input_data[0].split(":"))
distance = Distance(*self.__input_data[1].split(":"))

result = 1
for i in range(time.size):
local_res = sum(
1
for j in range(time.sequence[i] + 1)
if j * (time.sequence[i] - j) > distance.sequence[i]
)
result *= local_res
return result

def _calculate_2(self) -> int: # 42948149
time = Time(*self.__input_data[0].split(":"))
distance = Distance(*self.__input_data[1].split(":"))

result = 1
local_res = sum(
1
for j in range(time.sequence_kernig + 1)
if j * (time.sequence_kernig - j) > distance.sequence_kernig
)
result *= local_res
return result
153 changes: 153 additions & 0 deletions y_2023/day7.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
from typing import List, Dict
from common.aoc import AoCDay
from pydantic.dataclasses import dataclass
from collections import Counter

RANK_TYPE = {
"Five of a kind": 1,
"Four of a kind": 2,
"Full house": 3,
"Three of a kind": 4,
"Two pair": 5,
"One pair": 6,
"High card": 7,
}
RANK_CARD = {
"A": 1,
"K": 2,
"Q": 3,
"J": 4,
"T": 5,
"9": 6,
"8": 7,
"7": 8,
"6": 9,
"5": 10,
"4": 11,
"3": 12,
"2": 13,
}
RANK_CARD_2 = {k: v if k != "J" else 14 for k, v in RANK_CARD.items()}


@dataclass
class Hand:
cards: str

def sort_ord(self, type: str) -> List[int]:
if type == "original":
return [RANK_CARD[i] for i in self.cards]
if type == "joker":
return [RANK_CARD_2[i] for i in self.cards]
return []

@property
def __rate(self) -> str:
cou = Counter(self.cards)
if cou.most_common()[0][1] == 5:
# Five of a kind, where all five cards have the same label: AAAAA
return "Five of a kind" # , cou.most_common()[0][0]
if cou.most_common()[0][1] == 4:
# Four of a kind, where four cards have the same label and one card
# has a different label: AA8AA
return "Four of a kind" # , cou.most_common()[0][0]
if cou.most_common()[0][1] == 3 and cou.most_common()[1][1] == 2:
# Full house, where three cards have the same label, and the
# remaining two cards share a different label: 23332
return "Full house" # , cou.most_common()[0][0], cou.most_common()[1][0]
if cou.most_common()[0][1] == 3:
# Full house, where three cards have the same label, and the
# remaining two cards share a different label: 23332
return "Three of a kind" # , cou.most_common()[0][0]
if cou.most_common()[0][1] == 2 and cou.most_common()[1][1] == 2:
# Full house, where three cards have the same label, and the
# remaining two cards share a different label: 23332
return "Two pair" # , cou.most_common()[0][0], cou.most_common()[1][0]
if cou.most_common()[0][1] == 2:
# Full house, where three cards have the same label, and the
# remaining two cards share a different label: 23332
return "One pair" # , cou.most_common()[0][0]

return "High card" # , None

def rate(self, type: str) -> str:
if type != "joker" or "J" not in self.cards:
return self.__rate
str_clone = self.cards
cou = Counter(self.cards)

if cou.most_common()[0][1] > 1 and cou.most_common()[0][0] != "J":
str_clone = str_clone.replace("J", cou.most_common()[0][0])
if (
cou.most_common()[0][1] > 1
and cou.most_common()[0][0] == "J"
and cou.most_common()[0][1] < 5
):
str_clone = str_clone.replace("J", cou.most_common()[1][0])
if cou.most_common()[0][1] == 1 and cou.most_common()[0][0] == "J":
str_clone = str_clone.replace("J", cou.most_common()[1][0])
if cou.most_common()[0][1] == 1 and cou.most_common()[0][0] != "J":
str_clone = str_clone.replace("J", cou.most_common()[0][0])

cou = Counter(str_clone)
if cou.most_common()[0][1] == 5:
# Five of a kind, where all five cards have the same label: AAAAA
return "Five of a kind" # , cou.most_common()[0][0]
if cou.most_common()[0][1] == 4:
# Four of a kind, where four cards have the same label and one
# card has a different label: AA8AA
return "Four of a kind" # , cou.most_common()[0][0]
if cou.most_common()[0][1] == 3 and cou.most_common()[1][1] == 2:
# Full house, where three cards have the same label, and the
# remaining two cards share a different label: 23332
return "Full house" # , cou.most_common()[0][0], cou.most_common()[1][0]
if cou.most_common()[0][1] == 3:
# Full house, where three cards have the same label, and the
# remaining two cards share a different label: 23332
return "Three of a kind" # , cou.most_common()[0][0]
if cou.most_common()[0][1] == 2 and cou.most_common()[1][1] == 2:
# Full house, where three cards have the same label, and the
# remaining two cards share a different label: 23332
return "Two pair" # , cou.most_common()[0][0], cou.most_common()[1][0]
if cou.most_common()[0][1] == 2:
# Full house, where three cards have the same label, and the
# remaining two cards share a different label: 23332
return "One pair" # , cou.most_common()[0][0]

return "High card" # , None


@dataclass
class Row:
hand: Hand
bid: int


class Day(AoCDay):
def __init__(self, test=0):
super().__init__(__name__, test)

def _preprocess_input(self):
self.__input_data = [
(lambda x, y: Row(Hand(x), y))(*i.split()) for i in self._input_data[0]
]

def __compute(self, type: str) -> int:
ranks: Dict[str, List[Row]] = {i: [] for i in RANK_TYPE}
for i in self.__input_data:
ranks[i.hand.rate(type)].append(i)

final_ordering = []
for i in ranks.values():
final_ordering.extend(sorted(list(i), key=lambda x: x.hand.sort_ord(type)))

return sum(
(len(final_ordering) - c) * int(i.bid)
for c, i in enumerate(final_ordering)
)

def _calculate_1(self) -> int: # 246424613
return self.__compute("original")

def _calculate_2(self) -> int: # 248256639
return self.__compute("joker")

0 comments on commit 452e5fa

Please sign in to comment.