58 lines
2.0 KiB
Python
58 lines
2.0 KiB
Python
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 __str__(self):
|
|
return f"{self.value} = ({self.left}, {self.right})"
|
|
|
|
|
|
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 |