Compare commits
No commits in common. "3d1582f68578472dbfe8213e6fa5c594f9f2cccb" and "52001b9e1f4f55f2bd0ef48194b04e1255c183b2" have entirely different histories.
3d1582f685
...
52001b9e1f
@ -1,127 +0,0 @@
|
|||||||
from typing import List
|
|
||||||
from dataclasses import dataclass
|
|
||||||
|
|
||||||
card_order = ["A", "K", "Q", "J", "T", "9", "8", "7", "6", "5", "4", "3", "2"]
|
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
|
||||||
class Card:
|
|
||||||
card: str
|
|
||||||
|
|
||||||
def __lt__(self, other):
|
|
||||||
return card_order.index(self.card) > card_order.index(other.card)
|
|
||||||
|
|
||||||
def __eq__(self, other):
|
|
||||||
return self.card == other.card
|
|
||||||
|
|
||||||
def __ne__(self, other):
|
|
||||||
return not self.__eq__(other)
|
|
||||||
|
|
||||||
def __ge__(self, other):
|
|
||||||
return not self.__lt__(other)
|
|
||||||
|
|
||||||
def __gt__(self, other):
|
|
||||||
return not self.__lt__(other) and self.__ne__(other)
|
|
||||||
|
|
||||||
def __le__(self, other):
|
|
||||||
return not self.__gt__(other)
|
|
||||||
|
|
||||||
@dataclass(init=False,eq=False)
|
|
||||||
class Hand:
|
|
||||||
cards: List[Card]
|
|
||||||
bid: int
|
|
||||||
|
|
||||||
def __init__(self, cards:str, bid: str):
|
|
||||||
self.bid = int(bid)
|
|
||||||
self.cards = []
|
|
||||||
for card in cards:
|
|
||||||
self.cards.append(Card(card=card))
|
|
||||||
|
|
||||||
def _is_five_of_a_kind(self):
|
|
||||||
return all(map(lambda c: c == self.cards[0], self.cards[1:]))
|
|
||||||
|
|
||||||
def _is_four_of_a_kind(self):
|
|
||||||
poss1 = list(filter(None, map(lambda c: c == self.cards[0], self.cards[0:])))
|
|
||||||
poss2 = list(filter(None, map(lambda c: c == self.cards[1], self.cards[0:])))
|
|
||||||
return len(poss1) == 4 or len(poss2) == 4
|
|
||||||
|
|
||||||
def _is_full_house(self):
|
|
||||||
if not self._is_three_of_a_kind:
|
|
||||||
return False
|
|
||||||
if self.cards[0] != self.cards[1]:
|
|
||||||
c1 = list(filter(None, map(lambda c: c == self.cards[0], self.cards[0:])))
|
|
||||||
c2 = list(filter(None, map(lambda c: c == self.cards[1], self.cards[0:])))
|
|
||||||
return (len(c1) == 3 and len(c2) == 2) or (len(c1) == 2 and len(c2) == 3)
|
|
||||||
if self.cards[0] == self.cards[1] and self.cards[0] != self.cards[2]:
|
|
||||||
c1 = list(filter(None, map(lambda c: c == self.cards[0], self.cards[0:])))
|
|
||||||
c3 = list(filter(None, map(lambda c: c == self.cards[2], self.cards[0:])))
|
|
||||||
return (len(c1) == 3 and len(c3) == 2) or (len(c1) == 2 and len(c3) == 3)
|
|
||||||
if self.cards[0] == self.cards[1] and self.cards[0] == self.cards[2]:
|
|
||||||
return self.cards[3] == self.cards[4]
|
|
||||||
return False
|
|
||||||
|
|
||||||
def _is_three_of_a_kind(self):
|
|
||||||
poss1 = list(filter(None, map(lambda c: c == self.cards[0], self.cards[0:])))
|
|
||||||
poss2 = list(filter(None, map(lambda c: c == self.cards[1], self.cards[0:])))
|
|
||||||
poss3 = list(filter(None, map(lambda c: c == self.cards[2], self.cards[0:])))
|
|
||||||
return len(poss1) == 3 or len(poss2) == 3 or len(poss3) == 3
|
|
||||||
|
|
||||||
def _count_pairs(self):
|
|
||||||
sorted_cards = sorted(self.cards)
|
|
||||||
pairs = 0
|
|
||||||
for i in range(0, 4):
|
|
||||||
if sorted_cards[i] == sorted_cards[i + 1]:
|
|
||||||
pairs += 1
|
|
||||||
return pairs
|
|
||||||
|
|
||||||
def _is_two_pair(self):
|
|
||||||
pairs = self._count_pairs()
|
|
||||||
return pairs == 2
|
|
||||||
|
|
||||||
def _is_one_pair(self):
|
|
||||||
pairs = self._count_pairs()
|
|
||||||
return pairs == 1
|
|
||||||
|
|
||||||
def highest_card(self):
|
|
||||||
return max(self.cards)
|
|
||||||
|
|
||||||
def _rank(self):
|
|
||||||
if self._is_five_of_a_kind():
|
|
||||||
return 6
|
|
||||||
if self._is_four_of_a_kind():
|
|
||||||
return 5
|
|
||||||
if self._is_full_house():
|
|
||||||
return 4
|
|
||||||
if self._is_three_of_a_kind():
|
|
||||||
return 3
|
|
||||||
if self._is_two_pair():
|
|
||||||
return 2
|
|
||||||
if self._is_one_pair():
|
|
||||||
return 1
|
|
||||||
return 0
|
|
||||||
|
|
||||||
def __lt__(self, other):
|
|
||||||
if self._rank() < other._rank():
|
|
||||||
return True
|
|
||||||
if self._rank() == other._rank():
|
|
||||||
for i in range(5):
|
|
||||||
if self.cards[i] < other.cards[i]:
|
|
||||||
return True
|
|
||||||
if self.cards[i] > other.cards[i]:
|
|
||||||
return False
|
|
||||||
return False
|
|
||||||
|
|
||||||
def __eq__(self, other):
|
|
||||||
return all([self.cards[i] == other.cards[i] for i in range(len(self.cards))])
|
|
||||||
|
|
||||||
def __ne__(self, other):
|
|
||||||
return not self.__eq__(other)
|
|
||||||
|
|
||||||
def __ge__(self, other):
|
|
||||||
return not self.__lt__(other)
|
|
||||||
|
|
||||||
def __gt__(self, other):
|
|
||||||
return not self.__lt__(other) and self.__ne__(other)
|
|
||||||
|
|
||||||
def __le__(self, other):
|
|
||||||
return not self.__gt__(other)
|
|
@ -1,15 +0,0 @@
|
|||||||
from data_part1 import Hand
|
|
||||||
from pprint import pprint
|
|
||||||
|
|
||||||
input_file = 'input.txt'
|
|
||||||
hands = []
|
|
||||||
with open(input_file) as input:
|
|
||||||
while line:=input.readline():
|
|
||||||
cards, bid = line.replace("\n","").split(" ")
|
|
||||||
hands.append(Hand(cards=cards, bid=bid))
|
|
||||||
sorted_hands = sorted(hands)
|
|
||||||
pprint(sorted_hands)
|
|
||||||
sum = 0
|
|
||||||
for idx, hand in enumerate(sorted_hands):
|
|
||||||
sum += (idx + 1) * hand.bid
|
|
||||||
print(sum)
|
|
54
day8/data.py
54
day8/data.py
@ -1,54 +0,0 @@
|
|||||||
from __future__ import annotations
|
|
||||||
from typing import List, Tuple, Optional, Self
|
|
||||||
import weakref
|
|
||||||
from dataclasses import dataclass
|
|
||||||
import re
|
|
||||||
|
|
||||||
@dataclass
|
|
||||||
class Node:
|
|
||||||
value: str
|
|
||||||
left: str
|
|
||||||
right: str
|
|
||||||
_left_node: Optional[weakref.ReferenceType[Node]] = None
|
|
||||||
_right_node: Optional[weakref.ReferenceType[Node]] = None
|
|
||||||
|
|
||||||
def move_left(self, node_list: List[Node]) -> Node:
|
|
||||||
if self._left_node is None:
|
|
||||||
node = weakref.ref(list(filter(lambda n: n.value == self.left, node_list))[0])
|
|
||||||
self._left_node = node
|
|
||||||
return self._left_node()
|
|
||||||
|
|
||||||
def move_right(self, node_list: List[Node]) -> Node:
|
|
||||||
if self._right_node is None:
|
|
||||||
node = weakref.ref(list(filter(lambda n: n.value == self.right,node_list))[0])
|
|
||||||
self._right_node = node
|
|
||||||
return self._right_node()
|
|
||||||
|
|
||||||
def resolve_left_right_nodes(self, node_list: List[Node]) -> Self:
|
|
||||||
idx = 0
|
|
||||||
while idx < len(node_list) and (self._left_node is None or self._right_node is None):
|
|
||||||
if node_list[idx].value == self.left:
|
|
||||||
self._left_node = weakref.ref(node_list[idx])
|
|
||||||
if node_list[idx].value == self.right:
|
|
||||||
self._right_node = weakref.ref(node_list[idx])
|
|
||||||
idx += 1
|
|
||||||
if self._left_node == None or self._right_node == None:
|
|
||||||
print(f"Invalid Node: {self}")
|
|
||||||
return self
|
|
||||||
|
|
||||||
|
|
||||||
def is_A_node(self):
|
|
||||||
return self.value[2] == 'A'
|
|
||||||
def is_Z_node(self):
|
|
||||||
return self.value[2] == 'Z'
|
|
||||||
|
|
||||||
|
|
||||||
def parse(input_file:str) -> Tuple[str, List[Node]]:
|
|
||||||
the_list = []
|
|
||||||
with open(input_file) as input:
|
|
||||||
directions = input.readline().replace("\n","")
|
|
||||||
_ = input.readline()
|
|
||||||
while match:= re.match("([A-Z]+) = \(([A-Z]+), ([A-Z]+)\)",input.readline()):
|
|
||||||
node = Node(value=match.group(1), left=match.group(2), right=match.group(3))
|
|
||||||
the_list.append(node)
|
|
||||||
return directions, the_list
|
|
@ -1,21 +0,0 @@
|
|||||||
#!/usr/bin/env python3.11
|
|
||||||
from typing import List
|
|
||||||
|
|
||||||
from data import Node, parse
|
|
||||||
|
|
||||||
|
|
||||||
def count_steps_AAA_ZZZ(directions:str , node_list: List[Node]) -> int:
|
|
||||||
count = 0
|
|
||||||
current_node = list(filter(lambda n:n.value == 'AAA', node_list))[0]
|
|
||||||
while current_node.value != 'ZZZ':
|
|
||||||
current_node = current_node.move_left(node_list) if directions[count % len(directions)] == 'L' else current_node.move_right(node_list)
|
|
||||||
count += 1
|
|
||||||
return count
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
directions, node_list = parse('input.txt')
|
|
||||||
count = count_steps_AAA_ZZZ(directions, node_list)
|
|
||||||
print(count)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1,37 +0,0 @@
|
|||||||
#!/usr/bin/env python3.11
|
|
||||||
from typing import List, Tuple
|
|
||||||
from concurrent.futures import ThreadPoolExecutor
|
|
||||||
from threading import current_thread
|
|
||||||
from data import Node, parse
|
|
||||||
|
|
||||||
def count_steps_XXA_to_XXZ(node: Node, directions:str, node_list: List[Node]) -> int:
|
|
||||||
print(f"thread {current_thread().name} counting from {node}")
|
|
||||||
if not node.is_A_node():
|
|
||||||
raise Exception("node must be a XXA node")
|
|
||||||
count = 0
|
|
||||||
current_node = node
|
|
||||||
while not current_node.is_Z_node():
|
|
||||||
current_node = current_node.move_left(node_list) if directions[count % len(directions)] == 'L' else current_node.move_right(node_list)
|
|
||||||
count += 1
|
|
||||||
print(f"thread {current_thread().name} as counted {count} steps to {current_node}")
|
|
||||||
return count
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
directions, node_list = parse('input.txt')
|
|
||||||
print("solving all nodes")
|
|
||||||
solved_node_list = map(lambda node: node.resolve_left_right_nodes(node_list), node_list)
|
|
||||||
#print(node_list)
|
|
||||||
print("all_nodes_solved")
|
|
||||||
xxA_nodes = list(filter(lambda node: node.is_A_node(), solved_node_list))
|
|
||||||
print(xxA_nodes)
|
|
||||||
results = []
|
|
||||||
#Parallel version
|
|
||||||
#with ThreadPoolExecutor(max_workers=10) as executor:
|
|
||||||
# print("starting ThreadPool")
|
|
||||||
# for xxA_node in xxA_nodes:
|
|
||||||
# results.append(executor.submit(count_steps_XXA_to_XXZ, xxA_node, directions, solved_node_list))
|
|
||||||
#results = map(lambda exec: exec.result(), results)
|
|
||||||
results = [count_steps_XXA_to_XXZ(xxA_node, directions, solved_node_list) for xxA_node in xxA_nodes]
|
|
||||||
print(results)
|
|
||||||
print(sum(results))
|
|
||||||
|
|
75
q
Normal file
75
q
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
[33mcommit 028c13fbba8bb94d3cad5d5d5d6509923c6be082[m[33m ([m[1;36mHEAD -> [m[1;32mmain[m[33m)[m
|
||||||
|
Author: Fedaya <fedaya@fedaya.net>
|
||||||
|
Date: Wed Dec 6 22:00:00 2023 +0100
|
||||||
|
|
||||||
|
Revert "Debugging of Day5/part2_time_hog.py"
|
||||||
|
|
||||||
|
This reverts commit bf7aac3b22c1e777a13674535ea4a869392acb12.
|
||||||
|
|
||||||
|
[33mcommit bf7aac3b22c1e777a13674535ea4a869392acb12[m
|
||||||
|
Author: Étienne Gille <etienne.gille@ville-lespontsdece.fr>
|
||||||
|
Date: Wed Dec 6 21:58:35 2023 +0100
|
||||||
|
|
||||||
|
Debugging of Day5/part2_time_hog.py
|
||||||
|
|
||||||
|
It now works in parallel, not in a timely manner, though
|
||||||
|
|
||||||
|
[33mcommit 8b2bac07914217eb8b57798e4d0f798953e8db9d[m[33m ([m[1;31morigin/main[m[33m, [m[1;31morigin/HEAD[m[33m)[m
|
||||||
|
Author: Fedaya <fedaya@fedaya.net>
|
||||||
|
Date: Wed Dec 6 08:12:32 2023 +0100
|
||||||
|
|
||||||
|
Day 6 completed
|
||||||
|
|
||||||
|
Day5 part 2 still ongoing
|
||||||
|
|
||||||
|
[33mcommit b588eeb7e5cc84aa6c61791ff7612edfc0116bb9[m
|
||||||
|
Author: Fedaya <fedaya@fedaya.net>
|
||||||
|
Date: Tue Dec 5 08:06:53 2023 +0100
|
||||||
|
|
||||||
|
First solution to part2
|
||||||
|
|
||||||
|
It's kind of a time hog, though
|
||||||
|
|
||||||
|
[33mcommit e46a2717b4c062a7d1bcf92f018a4c91538a9fcc[m
|
||||||
|
Author: Fedaya <fedaya@fedaya.net>
|
||||||
|
Date: Tue Dec 5 07:18:55 2023 +0100
|
||||||
|
|
||||||
|
Day 5 part1 completed
|
||||||
|
|
||||||
|
Also, deleted an example_input.txt, modified .gitignore
|
||||||
|
added a script to get the current day's input
|
||||||
|
|
||||||
|
[33mcommit 9ee98d375a929dd8b690e50f4b62e8b3460fdd8b[m
|
||||||
|
Author: Fedaya <fedaya@fedaya.net>
|
||||||
|
Date: Mon Dec 4 07:47:34 2023 +0100
|
||||||
|
|
||||||
|
Modified .gitignore to not include example_input.txt
|
||||||
|
|
||||||
|
[33mcommit 142696bf6e92ce3e97de220f03c0b57c2b9c0f2a[m
|
||||||
|
Author: Fedaya <fedaya@fedaya.net>
|
||||||
|
Date: Mon Dec 4 07:44:36 2023 +0100
|
||||||
|
|
||||||
|
Day 4 completed
|
||||||
|
|
||||||
|
+ refactored day 1 to 3 with black -l 119
|
||||||
|
|
||||||
|
[33mcommit 97021a58b2d41f64b55e4dcb8257dd859817cd95[m
|
||||||
|
Author: Fedaya <fedaya@fedaya.net>
|
||||||
|
Date: Sun Dec 3 08:41:27 2023 +0100
|
||||||
|
|
||||||
|
Part 3 completed
|
||||||
|
|
||||||
|
[33mcommit fbf1c66a3968f0f300cbb6d1895e71c515278a9e[m
|
||||||
|
Author: Fedaya <fedaya@fedaya.net>
|
||||||
|
Date: Sat Dec 2 12:45:07 2023 +0100
|
||||||
|
|
||||||
|
Nouveau Repository
|
||||||
|
|
||||||
|
Je perd l'historique, mais ne stocke plus les fichiers input.txt
|
||||||
|
entre autre choses
|
||||||
|
|
||||||
|
[33mcommit 3e06d85867ceffb21d59c949bef8049e8b0670ef[m
|
||||||
|
Author: Fedaya <fedaya@fedaya.net>
|
||||||
|
Date: Sat Dec 2 12:42:58 2023 +0100
|
||||||
|
|
||||||
|
Initial commit
|
Loading…
x
Reference in New Issue
Block a user