Day 8 part 1 completed, part 2 in progress
This commit is contained in:
54
day8/data.py
Normal file
54
day8/data.py
Normal file
@@ -0,0 +1,54 @@
|
||||
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
|
||||
21
day8/part1.py
Executable file
21
day8/part1.py
Executable file
@@ -0,0 +1,21 @@
|
||||
#!/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)
|
||||
|
||||
|
||||
|
||||
37
day8/part2.py
Executable file
37
day8/part2.py
Executable file
@@ -0,0 +1,37 @@
|
||||
#!/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))
|
||||
|
||||
Reference in New Issue
Block a user