From c5eacb4fbfa77e1d808591f41e8a2d153956f3ce Mon Sep 17 00:00:00 2001 From: Stegallo Date: Thu, 30 Nov 2023 22:40:13 -0800 Subject: [PATCH 1/5] day1 --- y_2023/day1.py | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 y_2023/day1.py diff --git a/y_2023/day1.py b/y_2023/day1.py new file mode 100644 index 0000000..ed684e0 --- /dev/null +++ b/y_2023/day1.py @@ -0,0 +1,47 @@ +from common.aoc import AoCDay + +SPELLED = ["one", "two", "three", "four", "five", "six", "seven", "eight", "nine"] + + +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): + # return 0 + # print(f"{self.__input_data=}") + s = 0 + for i in self.__input_data: + first = None + for j in i: + if j.isnumeric(): + first = int(j) + break + for j in i[::-1]: + if j.isnumeric(): + last = int(j) + break + s = s + first * 10 + last + return s + # return max(sum(i) for i in self.__input_data) + + def _calculate_2(self): + s = 0 + for i in self.__input_data: + for c, k in enumerate(SPELLED): + i = i.replace(k, k + str(c + 1) + k) + # print(f'{i=}') + first = None + for j in i: + if j.isnumeric(): + first = int(j) + break + for j in i[::-1]: + if j.isnumeric(): + last = int(j) + break + s = s + first * 10 + last + return s From 763d0bae47c5d58d0b143a686e9afa22f67af1d4 Mon Sep 17 00:00:00 2001 From: Stegallo Date: Thu, 7 Dec 2023 15:44:12 -0800 Subject: [PATCH 2/5] first 7 days --- tests/y_2023/test_2023_day5.py | 45 +++++++++ tests/y_2023/test_2023_day7.py | 54 ++++++++++ y_1900/day0.py | 6 +- y_2023/day2.py | 52 ++++++++++ y_2023/day3.py | 128 +++++++++++++++++++++++ y_2023/day4.py | 65 ++++++++++++ y_2023/day5.py | 167 ++++++++++++++++++++++++++++++ y_2023/day6.py | 62 ++++++++++++ y_2023/day7.py | 179 +++++++++++++++++++++++++++++++++ 9 files changed, 755 insertions(+), 3 deletions(-) create mode 100644 tests/y_2023/test_2023_day5.py create mode 100644 tests/y_2023/test_2023_day7.py create mode 100644 y_2023/day2.py create mode 100644 y_2023/day3.py create mode 100644 y_2023/day4.py create mode 100644 y_2023/day5.py create mode 100644 y_2023/day6.py create mode 100644 y_2023/day7.py diff --git a/tests/y_2023/test_2023_day5.py b/tests/y_2023/test_2023_day5.py new file mode 100644 index 0000000..ceb944c --- /dev/null +++ b/tests/y_2023/test_2023_day5.py @@ -0,0 +1,45 @@ +from __future__ import annotations + +from unittest.mock import mock_open, patch + +from y_2023.day5 import Day, SeedRange + +with patch("builtins.open", mock_open(read_data="0")): + day = Day() + +def test_SeedRange_split(): + print() + sr = SeedRange(5,10) + n_sr = sr.split(6,9) + print(n_sr) + assert n_sr == [SeedRange(5,5), SeedRange(6,9), SeedRange(10,10)] + n_sr = sr.split(4,11) + print(n_sr) + assert n_sr == [SeedRange(5,10)] + n_sr = sr.split(4,9) + print(n_sr) + assert n_sr == [SeedRange(5,9), SeedRange(10,10)] + n_sr = sr.split(6,11) + print(n_sr) + assert n_sr == [SeedRange(5,5), SeedRange(6,10)] + + sr = SeedRange(79,93) + n_sr = sr.split(98,99) + print(n_sr) + assert n_sr == [SeedRange(79,93)] + + sr = SeedRange(81,95) + n_sr = sr.split(25,94) + print(n_sr) + assert n_sr == [SeedRange(81,94), SeedRange(95,95)] + + +def test__preprocess_input(): + assert True + + +def test_calculate_1(): + assert True + +def test_calculate_2(): + assert True diff --git a/tests/y_2023/test_2023_day7.py b/tests/y_2023/test_2023_day7.py new file mode 100644 index 0000000..c7894cd --- /dev/null +++ b/tests/y_2023/test_2023_day7.py @@ -0,0 +1,54 @@ +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")): + day = Day() + +def test_Hand(): + print() + h = Hand('32T3K') + h = Hand('3333K') + print(h) + print(h.rate()) + assert True + +def test_Hand_five(): + h = Hand('AAAAA') + assert h.rate() == ('Five of a kind','A') + +def test_Hand_four(): + h = Hand('AA8AA') + assert h.rate() == ('Four of a kind','A') + +def test_Hand_full(): + h = Hand('23332') + assert h.rate() == ('Full house','3','2') + +def test_Hand_three(): + h = Hand('AA8A9') + assert h.rate() == ('Three of a kind','A') + +def test_Hand_two_pair(): + h = Hand('AA898') + assert h.rate() == ('Two pair','A','8') + +def test_Hand_one_pair(): + h = Hand('AA8J9') + assert h.rate() == ('One pair','A') + +def test_Hand_high_card(): + h = Hand('23456') + assert h.rate() == ('High card', None) + +def test__preprocess_input(): + assert True + + +def test_calculate_1(): + assert True + +def test_calculate_2(): + assert True diff --git a/y_1900/day0.py b/y_1900/day0.py index 2a6ff1b..56cc7a5 100644 --- a/y_1900/day0.py +++ b/y_1900/day0.py @@ -11,11 +11,11 @@ def _preprocess_input(self): self.__input_data = self._input_data[0] def _calculate_1(self): - x = self.__input_data - print(f"{x=}") + for x in self.__input_data: + print(f"{x}") return 0 def _calculate_2(self): + return 0 x = self.__input_data print(f"{x=}") - return 0 diff --git a/y_2023/day2.py b/y_2023/day2.py new file mode 100644 index 0000000..d157fe1 --- /dev/null +++ b/y_2023/day2.py @@ -0,0 +1,52 @@ +from common.aoc import AoCDay + +MAX_N = {"red": 12, "green": 13, "blue": 14} + + +class Day(AoCDay): + def __init__(self, test=0): + super().__init__(__name__, test) + + def _preprocess_input(self): + # self.__input_data = [[int(i) for i in chunk] for chunk in self._input_data] + # print(f"{self._input_data=}") + self.__input_data = self._input_data[0] + + def _calculate_1(self): + result = 0 + x = self.__input_data + for game in x: + pairs = game.split(": ")[1].split("; ") + # print(f"{pairs=}, {len(pairs)=}") + possible = True + for pair in pairs: + print(pair.split(", ")) + for m in pair.split(", "): + tuple = m.split(" ") + # print(f"{tuple=}") + if int(tuple[0]) > MAX_N[tuple[1]]: + # print('impossibl') + possible = False + if possible: + result += int(game.split(":")[0].split(" ")[1]) + print(result) + return result + + def _calculate_2(self): + result = 0 + for game in self.__input_data: + max_n = {"red": 0, "green": 0, "blue": 0} + pairs = game.split(": ")[1].split("; ") + for pair in pairs: + # print(pair.split(', ')) + for m in pair.split(", "): + tuple = m.split(" ") + # print(f"{tuple}") + if int(tuple[0]) > max_n[tuple[1]]: + max_n[tuple[1]] = int(tuple[0]) + print(max_n) + power = max_n["red"] * max_n["green"] * max_n["blue"] + result += power + return result + x = self.__input_data + print(f"{x=}") diff --git a/y_2023/day3.py b/y_2023/day3.py new file mode 100644 index 0000000..bc371b4 --- /dev/null +++ b/y_2023/day3.py @@ -0,0 +1,128 @@ +from common.aoc import AoCDay +from collections import defaultdict + +class Day(AoCDay): + def __init__(self, test=0): + super().__init__(__name__, test) + + def _preprocess_input(self): + # self.__input_data = [[int(i) for i in chunk] for chunk in self._input_data] + # print(f"{self._input_data=}") + self.__input_data = self._input_data[0] + + def _calculate_1(self): + result = 0 + simbols={} + for c, x in enumerate(self.__input_data): + # print(f"{x=}") + # print(f"{x.split('.')=}") + for d, y in enumerate(x): + if y != '.' and not y.isnumeric(): + simbols[(c,d)] = y + # print(simbols) + for c, x in enumerate(self.__input_data): + splits = x.split('.') + numbers = [] + for i in splits: + if i.isnumeric(): + numbers.append(i) + elif i[:-1].isnumeric(): + numbers.append(i[:-1]) + elif i[1:].isnumeric(): + numbers.append(i[1:]) + elif len(i)>1: + # print(i) + j = i.split('*') + numbers.extend(j) + # 1/0 + # print(f'{numbers=}') + # continue + num_ind = 0 + start = 0 + end = 0 + while x: + # print(x, x[0], numbers, num_ind, start, end) + if num_ind>=len(numbers): + break + if x[0]=='.' or not x[0].isnumeric(): + x=x[1:] + start += 1 + if x.startswith(str(numbers[num_ind])): + end = start+ len(str(numbers[num_ind]))-1 + # print(numbers[num_ind], start, end) + for k in range(c-1, c+2): + for l in range(start-1, end +2): + # print((k,l), simbols.get((k,l))) + if simbols.get((k,l)): + # print(int(numbers[num_ind])) + result+=int(numbers[num_ind]) + start = end+1 + x=x[len(str(numbers[num_ind])):] + num_ind += 1 + + # break + + return result + + def _calculate_2(self): + result = 0 + simbols={} + new_simbols=defaultdict(list) + for c, x in enumerate(self.__input_data): + # print(f"{x=}") + # print(f"{x.split('.')=}") + for d, y in enumerate(x): + if y != '.' and not y.isnumeric(): + simbols[(c,d)] = (y,[]) + # print(simbols) + for c, x in enumerate(self.__input_data): + splits = x.split('.') + numbers = [] + for i in splits: + if i.isnumeric(): + numbers.append(i) + elif i[:-1].isnumeric(): + numbers.append(i[:-1]) + elif i[1:].isnumeric(): + numbers.append(i[1:]) + elif len(i)>1: + # print(i) + j = i.split('*') + numbers.extend(j) + # 1/0 + # print(f'{numbers=}') + # continue + num_ind = 0 + start = 0 + end = 0 + while x: + # print(x, x[0], numbers, num_ind, start, end) + if num_ind>=len(numbers): + break + if x[0]=='.' or not x[0].isnumeric(): + x=x[1:] + start += 1 + if x.startswith(str(numbers[num_ind])): + end = start+ len(str(numbers[num_ind]))-1 + # print(numbers[num_ind], start, end) + for k in range(c-1, c+2): + for l in range(start-1, end +2): + # print((k,l), simbols.get((k,l))) + if simbols.get((k,l)): + # print(int(numbers[num_ind])) + # result+=int(numbers[num_ind]) + new_simbols[k,l].append(int(numbers[num_ind])) + start = end+1 + x=x[len(str(numbers[num_ind])):] + num_ind += 1 + + # break + print(new_simbols) + for i in simbols: + if simbols[i][0] == '*' and len(new_simbols[i])==2: + print(simbols[i]) + print(new_simbols[i]) + print( new_simbols[i][0]*new_simbols[i][1] ) + result+=new_simbols[i][0]*new_simbols[i][1] + + return result diff --git a/y_2023/day4.py b/y_2023/day4.py new file mode 100644 index 0000000..af551cf --- /dev/null +++ b/y_2023/day4.py @@ -0,0 +1,65 @@ +from common.aoc import AoCDay +from pydantic.dataclasses import dataclass +from collections import deque +@dataclass +class Card: + name: str + win: set + have: set + + +class Day(AoCDay): + def __init__(self, test=0): + super().__init__(__name__, test) + + def _preprocess_input(self): + self.__input_data = [] + for i in self._input_data[0]: + win = set([x for x in i.split(': ' )[1].split(' | ')[0].split(' ') if x]) + have = set([x for x in i.split(': ' )[1].split(' | ')[1].split(' ') if x]) + self.__input_data.append(Card(i.split(': ' )[0], win, have)) + + + def _calculate_1(self): + result = 0 + for i in self.__input_data: + # print(f"{i.win}, {i.have}") + if len(i.win.intersection(i.have)) > 0: + res =pow(2, len(i.win.intersection(i.have))-1) + result += res + return result + + def _calculate_2(self): + result = 0 + + deck={} + original_deck = self.__input_data + for i in original_deck: + deck[i.name] = 1 + print(deck) + for c, i in enumerate(original_deck): + # print(f"{i}") + # print(f"{i.name}, {len(i.win.intersection(i.have))}") + res =len(i.win.intersection(i.have)) + # print(res) + for j in range(res): + # print(original_deck[c+j+1]) + deck[original_deck[c+j+1].name] += 1*deck[i.name] + # + print(sum(deck.values())) + # while x: + # i=x.popleft() + # print(f"{i}") + # # print(f"{i.win}, {i.have}, {i.win.intersection(i.have)}") + # print(f"{len(i.win.intersection(i.have))=}") + # # + # res =len(i.win.intersection(i.have)) + # print(res) + # for j in range(res): + # x.append(x[j]) + # c+=1 + # if c==6: + # break + # for i in x: + # print(i) + return 0 diff --git a/y_2023/day5.py b/y_2023/day5.py new file mode 100644 index 0000000..5275262 --- /dev/null +++ b/y_2023/day5.py @@ -0,0 +1,167 @@ +from common.aoc import AoCDay +from pprint import pprint +from collections import deque +from pydantic.dataclasses import dataclass + +def mapp(input, mapping): + # print(mapping) + output = input + for m in mapping: + if int(input) >= m[0] and int(input) <= m[1]: + output = int(input) - m[0] + m[2] + return output # + # return mapping.get(int(input), int(input)) + +# def collapse_rages(rang): +# breakpoint() +# fixed +# while not fixed: +# + +def mapp_range(input, mapping): + # print(f"at start: {input}, {mapping}") + # sorted_i = sorted(input, key=lambda x: x.start) + # print(f"sorted_i: {sorted_i}") + # for i in range(len(sorted_i)-1): + # if sorted_i[i].end>=sorted_i[i+1].start: + # input=collapse_rages(sorted_i) + # break + + # new_input = [i for i in input] + # breakpoint() + for i in mapping: + new_input = [] + for j in input: + # print(f"{i[0]=},{i[1]=}") + new_input.extend(j.split(i[0],i[1])) + input = [i for i in new_input] + # print(f" in progress: {input}, {mapping}") + # print(f"at end : {input}, {mapping}") + + print_inp = list(input) + output = [] + for inp in input: + processed = False + for m in mapping: + # print(f"{m=}") + # if m[0]==77: + # breakpoint() + + if inp.start >= m[0] and inp.end <= m[1]: + output.append(SeedRange(inp.start- m[0] + m[2], inp.end- m[0] + m[2])) + processed=True + # else: + # output.append(inp) + # breakpoint() + if not processed: + output.append(inp) + # input = list(output) + # print(f"{print_inp=}, {output=}") + return output + +@dataclass +class SeedRange: + start:int + end:int + size:int = 0 + + def __post_init__(self) -> None: + self.size = self.end-self.start+1 + + # @property + # def size(self): + # return self.end-self.start + + def split(self, s, e): + result = [] + # breakpoint() + if self.end < s: + return [self] + if self.start > e: + return [self] + if self.start < s and self.end > e: + result.append(SeedRange(self.start, s-1)) + result.append(SeedRange(s, e)) + result.append(SeedRange(e+1, self.end)) + if not self.start < s and self.end > e: + result.append(SeedRange(self.start, e)) + result.append(SeedRange(e+1, self.end)) + if self.start < s and not self.end > e: + result.append(SeedRange(self.start, s-1)) + result.append(SeedRange(s, self.end)) + if not result: + return [self] + return result + +class Day(AoCDay): + def __init__(self, test=0): + super().__init__(__name__, test) + + def _preprocess_input(self): + # self.__input_data = [[int(i) for i in chunk] for chunk in self._input_data] + # print(f"{self._input_data=}") + self.__input_data = self._input_data + + def _calculate_1(self): + return 0 + seeds = self.__input_data[0][0].split(': ')[1].split(' ') + map = [] + for c, x in enumerate(self.__input_data[1:]): + map.append([]) + # map.append({}) + for y in x[1:]: + d, s, r = [int(i) for i in y.split(' ')] + map[c].append((s, s+r-1, d)) + # for i in range(r): + # map[c][s+i] = d+i + # print(map) + print(seeds) + # pprint(map) + for x in map: + # seeds = [x.get(int(s), s) for s in seeds] + seeds = [mapp(s, x) for s in seeds] + print(seeds) + return min(seeds) + + def _calculate_2(self): + seeds = self.__input_data[0][0].split(': ')[1].split(' ') + map = [] + for c, x in enumerate(self.__input_data[1:]): + map.append([]) + # map.append({}) + for y in x[1:]: + d, s, r = [int(i) for i in y.split(' ')] + map[c].append((s, s+r-1, d)) + # for i in range(r): + # map[c][s+i] = d+i + # print(map) + print(seeds) + + + seeds_new = [] + for c, k in enumerate(seeds): + # print(c, k, seeds) + if c % 2 != 0: + # print(c, k, seeds) + # for i in range(int(k)): + # seeds_new.append(int(seeds[c-1])+i) + # print(int(seeds[c-1]), int(seeds[c-1])+int(k)) + seeds_new.append(SeedRange(int(seeds[c-1]), int(seeds[c-1])+int(k)-1)) + # for i in range(int(d)): + # seeds_new.append(int(c)+i) + # print(f"{seeds_new}") + # breakpoint() + # return 0 + # pprint(map) + result = 1_000_000_000 + for x in map: + # # seeds = [x.get(int(s), s) for s in seeds] + # seeds_new = [mapp_range(s, x) for s in seeds_new] + seeds_new = mapp_range(seeds_new, x) + # print(seeds_new, sum(i.size for i in seeds_new)) + # return + for i in seeds_new: + if i.start < result: + result=i.start + # print(i.start) + return result # min(seeds_new) diff --git a/y_2023/day6.py b/y_2023/day6.py new file mode 100644 index 0000000..78014de --- /dev/null +++ b/y_2023/day6.py @@ -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 = [[int(i) for i in chunk] for chunk in self._input_data] + # print(f"{self._input_data=}") + self.__input_data = self._input_data[0] + + def _calculate_1(self): + time = Time(*self.__input_data[0].split(':')) + distance = Distance(*self.__input_data[1].split(':')) + # print(time, distance) + result = 1 + for i in range(time.size): + # print(time.sequence[i]) + # print(distance.sequence[i]) + local_res = 0 + for j in range(time.sequence[i]+1): + # print(j, time.sequence[i]-j, j*(time.sequence[i]-j)) + if j*(time.sequence[i]-j) >distance.sequence[i]: + local_res+=1 + # print(f"{local_res=}") + result*=local_res # break + return result + + def _calculate_2(self): + time = Time(*self.__input_data[0].split(':')) + distance = Distance(*self.__input_data[1].split(':')) + print(time, distance) + result = 1 + local_res = 0 + for j in range(time.sequence_kernig+1): + # print(j, time.sequence[i]-j, j*(time.sequence[i]-j)) + if j*(time.sequence_kernig-j) >distance.sequence_kernig: + local_res+=1 + result*=local_res + return result diff --git a/y_2023/day7.py b/y_2023/day7.py new file mode 100644 index 0000000..4c18384 --- /dev/null +++ b/y_2023/day7.py @@ -0,0 +1,179 @@ +from common.aoc import AoCDay +from typing import List, Optional +from pydantic.dataclasses import dataclass +from collections import Counter +from pprint import pprint +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 = { + "A":1, + "K":2, + "Q":3, + + "T":5, + "9":6, + "8":7, + "7":8, + "6":9, + "5":10, + "4":11, + "3":12, + "2":13, + "J":14, +} + +@dataclass +class Hand: + cards:str + # c_l:Optional[List[str]]= None + sort_ord:str=None + sort_ord_2:str=None + + def __post_init__(self) -> None: + # self.c_l = [i for i in self.cards] + self.sort_ord = [rank_card[i] for i in self.cards] + self.sort_ord_2 = [rank_card_2[i] for i in self.cards] + + def rate(self): + # breakpoint() + 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 rate2(self): + if "J" in self.cards: + # breakpoint() + str_clone = self.cards + cou = Counter(self.cards) + # print(cou) + 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 + else: + return self.rate() + # breakpoint() + + +class Day(AoCDay): + def __init__(self, test=0): + super().__init__(__name__, test) + + def _preprocess_input(self): + # self.__input_data = [[int(i) for i in chunk] for chunk in self._input_data] + # print(f"{self._input_data=}") + self.__input_data = self._input_data[0] + + def _calculate_1(self): + return 0 + hands = [] + for x in self.__input_data: + x, y = x.split() + # print(f"{x}") + hands.append((Hand(x), y)) + # print(hands) + ranks = {i: [] for i in rank_type} + for i in hands: + ranks[i[0].rate()[0]].append(i) + # pprint(ranks) + final_ordering = [] + for i in ranks.values(): + # print(sorted([x[0].sort_ord for x in i])) + # print(sorted([x for x in i], key = lambda x:x[0].sort_ord)) + final_ordering.extend(sorted([x for x in i], key = lambda x:x[0].sort_ord)) + # pprint(final_ordering) + result = 0 + for c, i in enumerate(final_ordering): + # print(len(final_ordering)-c, i) + result+=(len(final_ordering)-c) * int(i[1]) + + return result + + def _calculate_2(self): + hands = [] + for x in self.__input_data: + x, y = x.split() + # print(f"{x}") + hands.append((Hand(x), y)) + # print(hands) + ranks = {i: [] for i in rank_type} + for i in hands: + ranks[i[0].rate2()[0]].append(i) + pprint(ranks) + final_ordering = [] + for i in ranks.values(): + # print(sorted([x[0].sort_ord for x in i])) + # print(sorted([x for x in i], key = lambda x:x[0].sort_ord)) + final_ordering.extend(sorted([x for x in i], key = lambda x:x[0].sort_ord_2)) + # pprint(final_ordering) + result = 0 + for c, i in enumerate(final_ordering): + # print(len(final_ordering)-c, i) + result+=(len(final_ordering)-c) * int(i[1]) + + return result From 0ff6912a9533d8e1dd5c806cbb75ccee0dd19518 Mon Sep 17 00:00:00 2001 From: Stegallo Date: Fri, 8 Dec 2023 14:00:28 -0800 Subject: [PATCH 3/5] day1 --- tests/y_2023/test_2023_day5.py | 45 --------- tests/y_2023/test_2023_day7.py | 54 ---------- y_2023/day1.py | 54 +++++----- y_2023/day2.py | 52 ---------- y_2023/day3.py | 128 ----------------------- y_2023/day4.py | 65 ------------ y_2023/day5.py | 167 ------------------------------ y_2023/day6.py | 62 ------------ y_2023/day7.py | 179 --------------------------------- 9 files changed, 24 insertions(+), 782 deletions(-) delete mode 100644 tests/y_2023/test_2023_day5.py delete mode 100644 tests/y_2023/test_2023_day7.py delete mode 100644 y_2023/day2.py delete mode 100644 y_2023/day3.py delete mode 100644 y_2023/day4.py delete mode 100644 y_2023/day5.py delete mode 100644 y_2023/day6.py delete mode 100644 y_2023/day7.py diff --git a/tests/y_2023/test_2023_day5.py b/tests/y_2023/test_2023_day5.py deleted file mode 100644 index ceb944c..0000000 --- a/tests/y_2023/test_2023_day5.py +++ /dev/null @@ -1,45 +0,0 @@ -from __future__ import annotations - -from unittest.mock import mock_open, patch - -from y_2023.day5 import Day, SeedRange - -with patch("builtins.open", mock_open(read_data="0")): - day = Day() - -def test_SeedRange_split(): - print() - sr = SeedRange(5,10) - n_sr = sr.split(6,9) - print(n_sr) - assert n_sr == [SeedRange(5,5), SeedRange(6,9), SeedRange(10,10)] - n_sr = sr.split(4,11) - print(n_sr) - assert n_sr == [SeedRange(5,10)] - n_sr = sr.split(4,9) - print(n_sr) - assert n_sr == [SeedRange(5,9), SeedRange(10,10)] - n_sr = sr.split(6,11) - print(n_sr) - assert n_sr == [SeedRange(5,5), SeedRange(6,10)] - - sr = SeedRange(79,93) - n_sr = sr.split(98,99) - print(n_sr) - assert n_sr == [SeedRange(79,93)] - - sr = SeedRange(81,95) - n_sr = sr.split(25,94) - print(n_sr) - assert n_sr == [SeedRange(81,94), SeedRange(95,95)] - - -def test__preprocess_input(): - assert True - - -def test_calculate_1(): - assert True - -def test_calculate_2(): - assert True diff --git a/tests/y_2023/test_2023_day7.py b/tests/y_2023/test_2023_day7.py deleted file mode 100644 index c7894cd..0000000 --- a/tests/y_2023/test_2023_day7.py +++ /dev/null @@ -1,54 +0,0 @@ -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")): - day = Day() - -def test_Hand(): - print() - h = Hand('32T3K') - h = Hand('3333K') - print(h) - print(h.rate()) - assert True - -def test_Hand_five(): - h = Hand('AAAAA') - assert h.rate() == ('Five of a kind','A') - -def test_Hand_four(): - h = Hand('AA8AA') - assert h.rate() == ('Four of a kind','A') - -def test_Hand_full(): - h = Hand('23332') - assert h.rate() == ('Full house','3','2') - -def test_Hand_three(): - h = Hand('AA8A9') - assert h.rate() == ('Three of a kind','A') - -def test_Hand_two_pair(): - h = Hand('AA898') - assert h.rate() == ('Two pair','A','8') - -def test_Hand_one_pair(): - h = Hand('AA8J9') - assert h.rate() == ('One pair','A') - -def test_Hand_high_card(): - h = Hand('23456') - assert h.rate() == ('High card', None) - -def test__preprocess_input(): - assert True - - -def test_calculate_1(): - assert True - -def test_calculate_2(): - assert True diff --git a/y_2023/day1.py b/y_2023/day1.py index ed684e0..1047747 100644 --- a/y_2023/day1.py +++ b/y_2023/day1.py @@ -1,6 +1,17 @@ from common.aoc import AoCDay +from typing import List -SPELLED = ["one", "two", "three", "four", "five", "six", "seven", "eight", "nine"] +SPELLED = [ + "one", + "two", + "three", + "four", + "five", + "six", + "seven", + "eight", + "nine", +] class Day(AoCDay): @@ -10,38 +21,21 @@ def __init__(self, test=0): def _preprocess_input(self): self.__input_data = self._input_data[0] - def _calculate_1(self): - # return 0 - # print(f"{self.__input_data=}") + @staticmethod + def calculate_calibration(input: List[str]) -> int: s = 0 - for i in self.__input_data: - first = None - for j in i: - if j.isnumeric(): - first = int(j) - break - for j in i[::-1]: - if j.isnumeric(): - last = int(j) - break - s = s + first * 10 + last + for i in input: + j = [x for x in i if x.isnumeric()] + s += int(f"{j[0]}{j[-1]}") return s - # return max(sum(i) for i in self.__input_data) - def _calculate_2(self): - s = 0 + def _calculate_1(self) -> int: + return self.calculate_calibration(self.__input_data) + + def _calculate_2(self) -> int: + new_input = [] for i in self.__input_data: for c, k in enumerate(SPELLED): i = i.replace(k, k + str(c + 1) + k) - # print(f'{i=}') - first = None - for j in i: - if j.isnumeric(): - first = int(j) - break - for j in i[::-1]: - if j.isnumeric(): - last = int(j) - break - s = s + first * 10 + last - return s + new_input.append(i) + return self.calculate_calibration(new_input) diff --git a/y_2023/day2.py b/y_2023/day2.py deleted file mode 100644 index d157fe1..0000000 --- a/y_2023/day2.py +++ /dev/null @@ -1,52 +0,0 @@ -from common.aoc import AoCDay - -MAX_N = {"red": 12, "green": 13, "blue": 14} - - -class Day(AoCDay): - def __init__(self, test=0): - super().__init__(__name__, test) - - def _preprocess_input(self): - # self.__input_data = [[int(i) for i in chunk] for chunk in self._input_data] - # print(f"{self._input_data=}") - self.__input_data = self._input_data[0] - - def _calculate_1(self): - result = 0 - x = self.__input_data - for game in x: - pairs = game.split(": ")[1].split("; ") - # print(f"{pairs=}, {len(pairs)=}") - possible = True - for pair in pairs: - print(pair.split(", ")) - for m in pair.split(", "): - tuple = m.split(" ") - # print(f"{tuple=}") - if int(tuple[0]) > MAX_N[tuple[1]]: - # print('impossibl') - possible = False - if possible: - result += int(game.split(":")[0].split(" ")[1]) - print(result) - return result - - def _calculate_2(self): - result = 0 - for game in self.__input_data: - max_n = {"red": 0, "green": 0, "blue": 0} - pairs = game.split(": ")[1].split("; ") - for pair in pairs: - # print(pair.split(', ')) - for m in pair.split(", "): - tuple = m.split(" ") - # print(f"{tuple}") - if int(tuple[0]) > max_n[tuple[1]]: - max_n[tuple[1]] = int(tuple[0]) - print(max_n) - power = max_n["red"] * max_n["green"] * max_n["blue"] - result += power - return result - x = self.__input_data - print(f"{x=}") diff --git a/y_2023/day3.py b/y_2023/day3.py deleted file mode 100644 index bc371b4..0000000 --- a/y_2023/day3.py +++ /dev/null @@ -1,128 +0,0 @@ -from common.aoc import AoCDay -from collections import defaultdict - -class Day(AoCDay): - def __init__(self, test=0): - super().__init__(__name__, test) - - def _preprocess_input(self): - # self.__input_data = [[int(i) for i in chunk] for chunk in self._input_data] - # print(f"{self._input_data=}") - self.__input_data = self._input_data[0] - - def _calculate_1(self): - result = 0 - simbols={} - for c, x in enumerate(self.__input_data): - # print(f"{x=}") - # print(f"{x.split('.')=}") - for d, y in enumerate(x): - if y != '.' and not y.isnumeric(): - simbols[(c,d)] = y - # print(simbols) - for c, x in enumerate(self.__input_data): - splits = x.split('.') - numbers = [] - for i in splits: - if i.isnumeric(): - numbers.append(i) - elif i[:-1].isnumeric(): - numbers.append(i[:-1]) - elif i[1:].isnumeric(): - numbers.append(i[1:]) - elif len(i)>1: - # print(i) - j = i.split('*') - numbers.extend(j) - # 1/0 - # print(f'{numbers=}') - # continue - num_ind = 0 - start = 0 - end = 0 - while x: - # print(x, x[0], numbers, num_ind, start, end) - if num_ind>=len(numbers): - break - if x[0]=='.' or not x[0].isnumeric(): - x=x[1:] - start += 1 - if x.startswith(str(numbers[num_ind])): - end = start+ len(str(numbers[num_ind]))-1 - # print(numbers[num_ind], start, end) - for k in range(c-1, c+2): - for l in range(start-1, end +2): - # print((k,l), simbols.get((k,l))) - if simbols.get((k,l)): - # print(int(numbers[num_ind])) - result+=int(numbers[num_ind]) - start = end+1 - x=x[len(str(numbers[num_ind])):] - num_ind += 1 - - # break - - return result - - def _calculate_2(self): - result = 0 - simbols={} - new_simbols=defaultdict(list) - for c, x in enumerate(self.__input_data): - # print(f"{x=}") - # print(f"{x.split('.')=}") - for d, y in enumerate(x): - if y != '.' and not y.isnumeric(): - simbols[(c,d)] = (y,[]) - # print(simbols) - for c, x in enumerate(self.__input_data): - splits = x.split('.') - numbers = [] - for i in splits: - if i.isnumeric(): - numbers.append(i) - elif i[:-1].isnumeric(): - numbers.append(i[:-1]) - elif i[1:].isnumeric(): - numbers.append(i[1:]) - elif len(i)>1: - # print(i) - j = i.split('*') - numbers.extend(j) - # 1/0 - # print(f'{numbers=}') - # continue - num_ind = 0 - start = 0 - end = 0 - while x: - # print(x, x[0], numbers, num_ind, start, end) - if num_ind>=len(numbers): - break - if x[0]=='.' or not x[0].isnumeric(): - x=x[1:] - start += 1 - if x.startswith(str(numbers[num_ind])): - end = start+ len(str(numbers[num_ind]))-1 - # print(numbers[num_ind], start, end) - for k in range(c-1, c+2): - for l in range(start-1, end +2): - # print((k,l), simbols.get((k,l))) - if simbols.get((k,l)): - # print(int(numbers[num_ind])) - # result+=int(numbers[num_ind]) - new_simbols[k,l].append(int(numbers[num_ind])) - start = end+1 - x=x[len(str(numbers[num_ind])):] - num_ind += 1 - - # break - print(new_simbols) - for i in simbols: - if simbols[i][0] == '*' and len(new_simbols[i])==2: - print(simbols[i]) - print(new_simbols[i]) - print( new_simbols[i][0]*new_simbols[i][1] ) - result+=new_simbols[i][0]*new_simbols[i][1] - - return result diff --git a/y_2023/day4.py b/y_2023/day4.py deleted file mode 100644 index af551cf..0000000 --- a/y_2023/day4.py +++ /dev/null @@ -1,65 +0,0 @@ -from common.aoc import AoCDay -from pydantic.dataclasses import dataclass -from collections import deque -@dataclass -class Card: - name: str - win: set - have: set - - -class Day(AoCDay): - def __init__(self, test=0): - super().__init__(__name__, test) - - def _preprocess_input(self): - self.__input_data = [] - for i in self._input_data[0]: - win = set([x for x in i.split(': ' )[1].split(' | ')[0].split(' ') if x]) - have = set([x for x in i.split(': ' )[1].split(' | ')[1].split(' ') if x]) - self.__input_data.append(Card(i.split(': ' )[0], win, have)) - - - def _calculate_1(self): - result = 0 - for i in self.__input_data: - # print(f"{i.win}, {i.have}") - if len(i.win.intersection(i.have)) > 0: - res =pow(2, len(i.win.intersection(i.have))-1) - result += res - return result - - def _calculate_2(self): - result = 0 - - deck={} - original_deck = self.__input_data - for i in original_deck: - deck[i.name] = 1 - print(deck) - for c, i in enumerate(original_deck): - # print(f"{i}") - # print(f"{i.name}, {len(i.win.intersection(i.have))}") - res =len(i.win.intersection(i.have)) - # print(res) - for j in range(res): - # print(original_deck[c+j+1]) - deck[original_deck[c+j+1].name] += 1*deck[i.name] - # - print(sum(deck.values())) - # while x: - # i=x.popleft() - # print(f"{i}") - # # print(f"{i.win}, {i.have}, {i.win.intersection(i.have)}") - # print(f"{len(i.win.intersection(i.have))=}") - # # - # res =len(i.win.intersection(i.have)) - # print(res) - # for j in range(res): - # x.append(x[j]) - # c+=1 - # if c==6: - # break - # for i in x: - # print(i) - return 0 diff --git a/y_2023/day5.py b/y_2023/day5.py deleted file mode 100644 index 5275262..0000000 --- a/y_2023/day5.py +++ /dev/null @@ -1,167 +0,0 @@ -from common.aoc import AoCDay -from pprint import pprint -from collections import deque -from pydantic.dataclasses import dataclass - -def mapp(input, mapping): - # print(mapping) - output = input - for m in mapping: - if int(input) >= m[0] and int(input) <= m[1]: - output = int(input) - m[0] + m[2] - return output # - # return mapping.get(int(input), int(input)) - -# def collapse_rages(rang): -# breakpoint() -# fixed -# while not fixed: -# - -def mapp_range(input, mapping): - # print(f"at start: {input}, {mapping}") - # sorted_i = sorted(input, key=lambda x: x.start) - # print(f"sorted_i: {sorted_i}") - # for i in range(len(sorted_i)-1): - # if sorted_i[i].end>=sorted_i[i+1].start: - # input=collapse_rages(sorted_i) - # break - - # new_input = [i for i in input] - # breakpoint() - for i in mapping: - new_input = [] - for j in input: - # print(f"{i[0]=},{i[1]=}") - new_input.extend(j.split(i[0],i[1])) - input = [i for i in new_input] - # print(f" in progress: {input}, {mapping}") - # print(f"at end : {input}, {mapping}") - - print_inp = list(input) - output = [] - for inp in input: - processed = False - for m in mapping: - # print(f"{m=}") - # if m[0]==77: - # breakpoint() - - if inp.start >= m[0] and inp.end <= m[1]: - output.append(SeedRange(inp.start- m[0] + m[2], inp.end- m[0] + m[2])) - processed=True - # else: - # output.append(inp) - # breakpoint() - if not processed: - output.append(inp) - # input = list(output) - # print(f"{print_inp=}, {output=}") - return output - -@dataclass -class SeedRange: - start:int - end:int - size:int = 0 - - def __post_init__(self) -> None: - self.size = self.end-self.start+1 - - # @property - # def size(self): - # return self.end-self.start - - def split(self, s, e): - result = [] - # breakpoint() - if self.end < s: - return [self] - if self.start > e: - return [self] - if self.start < s and self.end > e: - result.append(SeedRange(self.start, s-1)) - result.append(SeedRange(s, e)) - result.append(SeedRange(e+1, self.end)) - if not self.start < s and self.end > e: - result.append(SeedRange(self.start, e)) - result.append(SeedRange(e+1, self.end)) - if self.start < s and not self.end > e: - result.append(SeedRange(self.start, s-1)) - result.append(SeedRange(s, self.end)) - if not result: - return [self] - return result - -class Day(AoCDay): - def __init__(self, test=0): - super().__init__(__name__, test) - - def _preprocess_input(self): - # self.__input_data = [[int(i) for i in chunk] for chunk in self._input_data] - # print(f"{self._input_data=}") - self.__input_data = self._input_data - - def _calculate_1(self): - return 0 - seeds = self.__input_data[0][0].split(': ')[1].split(' ') - map = [] - for c, x in enumerate(self.__input_data[1:]): - map.append([]) - # map.append({}) - for y in x[1:]: - d, s, r = [int(i) for i in y.split(' ')] - map[c].append((s, s+r-1, d)) - # for i in range(r): - # map[c][s+i] = d+i - # print(map) - print(seeds) - # pprint(map) - for x in map: - # seeds = [x.get(int(s), s) for s in seeds] - seeds = [mapp(s, x) for s in seeds] - print(seeds) - return min(seeds) - - def _calculate_2(self): - seeds = self.__input_data[0][0].split(': ')[1].split(' ') - map = [] - for c, x in enumerate(self.__input_data[1:]): - map.append([]) - # map.append({}) - for y in x[1:]: - d, s, r = [int(i) for i in y.split(' ')] - map[c].append((s, s+r-1, d)) - # for i in range(r): - # map[c][s+i] = d+i - # print(map) - print(seeds) - - - seeds_new = [] - for c, k in enumerate(seeds): - # print(c, k, seeds) - if c % 2 != 0: - # print(c, k, seeds) - # for i in range(int(k)): - # seeds_new.append(int(seeds[c-1])+i) - # print(int(seeds[c-1]), int(seeds[c-1])+int(k)) - seeds_new.append(SeedRange(int(seeds[c-1]), int(seeds[c-1])+int(k)-1)) - # for i in range(int(d)): - # seeds_new.append(int(c)+i) - # print(f"{seeds_new}") - # breakpoint() - # return 0 - # pprint(map) - result = 1_000_000_000 - for x in map: - # # seeds = [x.get(int(s), s) for s in seeds] - # seeds_new = [mapp_range(s, x) for s in seeds_new] - seeds_new = mapp_range(seeds_new, x) - # print(seeds_new, sum(i.size for i in seeds_new)) - # return - for i in seeds_new: - if i.start < result: - result=i.start - # print(i.start) - return result # min(seeds_new) diff --git a/y_2023/day6.py b/y_2023/day6.py deleted file mode 100644 index 78014de..0000000 --- a/y_2023/day6.py +++ /dev/null @@ -1,62 +0,0 @@ -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 = [[int(i) for i in chunk] for chunk in self._input_data] - # print(f"{self._input_data=}") - self.__input_data = self._input_data[0] - - def _calculate_1(self): - time = Time(*self.__input_data[0].split(':')) - distance = Distance(*self.__input_data[1].split(':')) - # print(time, distance) - result = 1 - for i in range(time.size): - # print(time.sequence[i]) - # print(distance.sequence[i]) - local_res = 0 - for j in range(time.sequence[i]+1): - # print(j, time.sequence[i]-j, j*(time.sequence[i]-j)) - if j*(time.sequence[i]-j) >distance.sequence[i]: - local_res+=1 - # print(f"{local_res=}") - result*=local_res # break - return result - - def _calculate_2(self): - time = Time(*self.__input_data[0].split(':')) - distance = Distance(*self.__input_data[1].split(':')) - print(time, distance) - result = 1 - local_res = 0 - for j in range(time.sequence_kernig+1): - # print(j, time.sequence[i]-j, j*(time.sequence[i]-j)) - if j*(time.sequence_kernig-j) >distance.sequence_kernig: - local_res+=1 - result*=local_res - return result diff --git a/y_2023/day7.py b/y_2023/day7.py deleted file mode 100644 index 4c18384..0000000 --- a/y_2023/day7.py +++ /dev/null @@ -1,179 +0,0 @@ -from common.aoc import AoCDay -from typing import List, Optional -from pydantic.dataclasses import dataclass -from collections import Counter -from pprint import pprint -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 = { - "A":1, - "K":2, - "Q":3, - - "T":5, - "9":6, - "8":7, - "7":8, - "6":9, - "5":10, - "4":11, - "3":12, - "2":13, - "J":14, -} - -@dataclass -class Hand: - cards:str - # c_l:Optional[List[str]]= None - sort_ord:str=None - sort_ord_2:str=None - - def __post_init__(self) -> None: - # self.c_l = [i for i in self.cards] - self.sort_ord = [rank_card[i] for i in self.cards] - self.sort_ord_2 = [rank_card_2[i] for i in self.cards] - - def rate(self): - # breakpoint() - 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 rate2(self): - if "J" in self.cards: - # breakpoint() - str_clone = self.cards - cou = Counter(self.cards) - # print(cou) - 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 - else: - return self.rate() - # breakpoint() - - -class Day(AoCDay): - def __init__(self, test=0): - super().__init__(__name__, test) - - def _preprocess_input(self): - # self.__input_data = [[int(i) for i in chunk] for chunk in self._input_data] - # print(f"{self._input_data=}") - self.__input_data = self._input_data[0] - - def _calculate_1(self): - return 0 - hands = [] - for x in self.__input_data: - x, y = x.split() - # print(f"{x}") - hands.append((Hand(x), y)) - # print(hands) - ranks = {i: [] for i in rank_type} - for i in hands: - ranks[i[0].rate()[0]].append(i) - # pprint(ranks) - final_ordering = [] - for i in ranks.values(): - # print(sorted([x[0].sort_ord for x in i])) - # print(sorted([x for x in i], key = lambda x:x[0].sort_ord)) - final_ordering.extend(sorted([x for x in i], key = lambda x:x[0].sort_ord)) - # pprint(final_ordering) - result = 0 - for c, i in enumerate(final_ordering): - # print(len(final_ordering)-c, i) - result+=(len(final_ordering)-c) * int(i[1]) - - return result - - def _calculate_2(self): - hands = [] - for x in self.__input_data: - x, y = x.split() - # print(f"{x}") - hands.append((Hand(x), y)) - # print(hands) - ranks = {i: [] for i in rank_type} - for i in hands: - ranks[i[0].rate2()[0]].append(i) - pprint(ranks) - final_ordering = [] - for i in ranks.values(): - # print(sorted([x[0].sort_ord for x in i])) - # print(sorted([x for x in i], key = lambda x:x[0].sort_ord)) - final_ordering.extend(sorted([x for x in i], key = lambda x:x[0].sort_ord_2)) - # pprint(final_ordering) - result = 0 - for c, i in enumerate(final_ordering): - # print(len(final_ordering)-c, i) - result+=(len(final_ordering)-c) * int(i[1]) - - return result From 78280053c9a516c6a7fab4f2904c04c6900a4511 Mon Sep 17 00:00:00 2001 From: Stegallo Date: Fri, 8 Dec 2023 14:13:44 -0800 Subject: [PATCH 4/5] day1 --- README.md | 27 +++++++++++++++------------ y_2023/day1.py | 10 +++++++--- 2 files changed, 22 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index 8133d20..02df006 100644 --- a/README.md +++ b/README.md @@ -8,19 +8,19 @@ for solutions in rust, refer to [rust repo][rustrepo] -| | 2015 | 2016 | 2017 | 2018 | 2019 | 2020 | 2021 | 2022 | +| | 2015 | 2016 | 2017 | 2018 | 2019 | 2020 | 2021 | 2022 | 2023 | | - | - | - | - | - | - | - | - | - | -| 01 | [puzzle][201501p]
[✓][201501] | | | | | | | [puzzle][202201p]
[✓][202201] | -| 02 | [puzzle][201502p]
[✓][201502] | | | | | | | | -| 03 | [puzzle][201503p]
[✓][201503] | | | | | | | | -| 04 | [puzzle][201504p]
[✓][201504] | | | | | | | | -| 05 | [puzzle][201505p]
[✓][201505] | | | | | | | | -| 06 | [puzzle][201506p]
[✓][201506] | | | | | | | | -| 07 | [puzzle][201507p]
[✓][201507] | | | | | | | | -| 08 | [puzzle][201508p]
[✓][201508] | | | | | | | | -| 09 | [puzzle][201509p]
[✓][201509] | | | | | | | | -| 10 | [puzzle][201510p]
[✓][201510] | | | | | | | | -| 11 | [puzzle][201511p]
[✓][201511] | | | | | | | | +| 01 | [puzzle][201501p]
[✓][201501] | | | | | | | [puzzle][202201p]
[✓][202201] | [puzzle][202301p]
[✓][202301] | +| 02 | [puzzle][201502p]
[✓][201502] | | | | | | | | | +| 03 | [puzzle][201503p]
[✓][201503] | | | | | | | | | +| 04 | [puzzle][201504p]
[✓][201504] | | | | | | | | | +| 05 | [puzzle][201505p]
[✓][201505] | | | | | | | | | +| 06 | [puzzle][201506p]
[✓][201506] | | | | | | | | | +| 07 | [puzzle][201507p]
[✓][201507] | | | | | | | | | +| 08 | [puzzle][201508p]
[✓][201508] | | | | | | | | | +| 09 | [puzzle][201509p]
[✓][201509] | | | | | | | | | +| 10 | [puzzle][201510p]
[✓][201510] | | | | | | | | | +| 11 | [puzzle][201511p]
[✓][201511] | | | | | | | | | [201501]: https://github.com/Stegallo/adventofcode/blob/master/y_2015/day1.py [201501p]: https://adventofcode.com/2015/day/1 @@ -48,6 +48,9 @@ for solutions in rust, refer to [rust repo][rustrepo] [202201]: https://github.com/Stegallo/adventofcode/blob/master/y_2022/day1.py [202201p]: https://adventofcode.com/2022/day/1 +[202301]: https://github.com/Stegallo/adventofcode/blob/master/y_2023/day1.py +[202301p]: https://adventofcode.com/2023/day/1 + [rustrepo]: https://github.com/Stegallo/adventofcodeinrust ## to run the code diff --git a/y_2023/day1.py b/y_2023/day1.py index 1047747..b8287d2 100644 --- a/y_2023/day1.py +++ b/y_2023/day1.py @@ -21,6 +21,12 @@ def __init__(self, test=0): def _preprocess_input(self): self.__input_data = self._input_data[0] + @staticmethod + def replace_word_with_number(input: str) -> str: + for c, k in enumerate(SPELLED): + input = input.replace(k, k + str(c + 1) + k) + return input + @staticmethod def calculate_calibration(input: List[str]) -> int: s = 0 @@ -35,7 +41,5 @@ def _calculate_1(self) -> int: def _calculate_2(self) -> int: new_input = [] for i in self.__input_data: - for c, k in enumerate(SPELLED): - i = i.replace(k, k + str(c + 1) + k) - new_input.append(i) + new_input.append(self.replace_word_with_number(i)) return self.calculate_calibration(new_input) From c236c64231d8e20bc43253006006f5fb7fcb6e43 Mon Sep 17 00:00:00 2001 From: Sourcery AI <> Date: Fri, 8 Dec 2023 22:14:01 +0000 Subject: [PATCH 5/5] 'Refactored by Sourcery' --- y_1900/day0.py | 2 -- y_2023/day1.py | 4 +--- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/y_1900/day0.py b/y_1900/day0.py index 56cc7a5..23edd15 100644 --- a/y_1900/day0.py +++ b/y_1900/day0.py @@ -17,5 +17,3 @@ def _calculate_1(self): def _calculate_2(self): return 0 - x = self.__input_data - print(f"{x=}") diff --git a/y_2023/day1.py b/y_2023/day1.py index b8287d2..787b989 100644 --- a/y_2023/day1.py +++ b/y_2023/day1.py @@ -39,7 +39,5 @@ def _calculate_1(self) -> int: return self.calculate_calibration(self.__input_data) def _calculate_2(self) -> int: - new_input = [] - for i in self.__input_data: - new_input.append(self.replace_word_with_number(i)) + new_input = [self.replace_word_with_number(i) for i in self.__input_data] return self.calculate_calibration(new_input)