Source code for sudokusolver.model.node

"""Provides Nodes and ReferenceNodes being part of the ConstraintMatrix."""

from .iterators import ColumnIterator, RowIterator


[docs]class Node(object): """ Simple data structure representing a node within a ConstraintMatrix. It know its left, bottom, right and top neighbour. In addition, it is also aware of the row and column it belongs to. """ def __init__(self, candidate, covered_constraint, row_ref_node=None, column_ref_node=None): self.top = None self.bottom = None self.left = None self.right = None self.candidate = candidate self.covered_constraint = covered_constraint self.row_ref_node = row_ref_node self.column_ref_node = column_ref_node @staticmethod
[docs] def connect(a: 'Node', b: 'Node', how: str): """Joins the given nodes **vertically** or **horizontally** together.""" if how.lower() == 'vertically': if a: a.bottom = b if b: b.top = a if how.lower() == 'horizontally': if a: a.right = b if b: b.left = a
@staticmethod
[docs] def disconnect(node: 'Node', how: str): """Disjoins the given node **vertically** or **horizontally** from its neighbours.""" if how.lower() == 'vertically': if node.left: node.left.right = node.right if node.right: node.right.left = node.left if how.lower() == 'horizontally': if node.top: node.top.bottom = node.bottom if node.bottom: node.bottom.top = node.top
def __repr__(self): return "Node('{}', '{}')".format(self.candidate, self.covered_constraint) def __str__(self): return "Node('{}', '{}')".format(self.candidate, self.covered_constraint) def __hash__(self): return hash((self.candidate, self.covered_constraint)) def __eq__(self, other): return (self.candidate, self.covered_constraint) == \ (other.candidate, other.covered_constraint)
[docs]class RowReferenceNode(Node): """ Special kind of node that refers another rode. Used by the ConstraintMatrix to address rows and iterate through their nodes. """ def __init__(self, candidate): super().__init__(candidate, '_', None, None) def __iter__(self): return iter(RowIterator(self.right))
[docs] def get_last_node(self): """Returns the last node of the row represented by this RowReferenceNode.""" if not self.right: return None nodes = [node for node in self] return nodes.pop()
[docs]class ColumnReferenceNode(Node): """ Special kind of node that refers another rode. Used by the ConstraintMatrix to address columns and iterate through their nodes. """ def __init__(self, covered_constraint): super().__init__('_', covered_constraint, None, None) self.size = 0 def __iter__(self): return iter(ColumnIterator(self.bottom))
[docs] def get_last_node(self) -> Node: """Returns the last node of the column represented by this ColumnReferenceNode.""" if not self.bottom: return None nodes = [node for node in self] return nodes.pop()
[docs]class MatrixHeadReferenceNode(Node): """ Special kind of node that refers to ColumnReferenceNodes and RowReferenceNodes. Used by the ConstraintMatrix to itereate through its columns and rows. """ def __init__(self): super().__init__('_', '_', None, None)
[docs] def get_last_column_ref_node(self) -> Node: """Returns the last ColumnReferenceNode in the matrix otherwise itself""" ref_nodes = [ref_node for ref_node in RowIterator(self)] return ref_nodes.pop()
[docs] def get_last_row_ref_node(self) -> Node: """Returns the last RowReferenceNode in the matrix otherwise itself""" ref_nodes = [ref_node for ref_node in ColumnIterator(self)] return ref_nodes.pop()
[docs] def get_column_ref_node_iterator(self): """Returns iterator iterating through the ColumnRerefernceNodes""" return RowIterator(self.right)
[docs] def get_row_ref_node_iterator(self): """Returns iterator iterating through the RowReferenceNodes""" return ColumnIterator(self.bottom)