+++ /dev/null
-from __future__ import division
-
-from weakref import ref
-
-class CellConstraint(object):
- """Represents any group of cells in a grid that cannot repeat a digit."""
-
- ### Accessors
-
- # NOTE: _cells is a list of refs; _grid is a ref
- # XXX document this
- cells = property(lambda self: [ x() for x in self._cells ])
- grid = property(lambda self: self._grid())
-
- ### Methods
- # XXX inherited __init__ to init _grid/_cells
-
- def find_value(self, value):
- """Returns the cells that can be a specific value."""
- possible_cells = []
- for cell in self.cells:
- if value in cell._values:
- possible_cells.append(cell)
-
- if len(possible_cells) == 0:
- raise Exception # XXX
-
- return possible_cells
-
- def resolve_uniques(self):
- for value in xrange(self.grid._size):
- # XXX cache values that are taken care of
- possible_cells = self.find_value(value)
-
- if len(possible_cells) > 1:
- # Not unique
- continue
-
- target_cell = possible_cells[0]
- if target_cell.solved:
- # Already seen this
- # XXX this is what cache is for
- continue
-
- # Only cell in the group that can be value
- target_cell.set(value)
-
-
-class Box(CellConstraint):
- def _get_box_row(self):
- return self._pos // self.grid._box_width
- box_row = property(_get_box_row)
-
- def _get_box_column(self):
- return self._pos % self.grid._box_height
- box_column = property(_get_box_column)
-
- def __init__(self, grid, position):
- self._grid = ref(grid)
- self._pos = position
-
- self._cells = []
- for row in xrange(self.grid._box_height):
- for col in xrange(self.grid._box_width):
- cell_row = row + self.box_row * self.grid._box_height
- cell_col = col + self.box_column * self.grid._box_width
- self._cells.append(ref(self.grid.cell(cell_row, cell_col)))
-
-
-class Row(CellConstraint):
- def __init__(self, grid, position):
- self._grid = ref(grid)
- self._pos = position
-
- self._cells = []
- for col in xrange(self.grid._size):
- self._cells.append(ref(self.grid.cell(self._pos, col)))
-
-class Column(CellConstraint):
- def __init__(self, grid, position):
- self._grid = ref(grid)
- self._pos = position
-
- self._cells = []
- for row in xrange(self.grid._size):
- self._cells.append(ref(self.grid.cell(row, self._pos)))
-
-class Diagonal(CellConstraint):
- def __init__(self, grid, direction='down', offset=0):
- self._grid = ref(grid)
- self._direction = direction
- self._offset = offset
-
- if direction == 'down':
- coords = {'row': 0, 'column': 0}
- increment = 1
- elif direction == 'up':
- coords = {'row': 0, 'column': grid.size - 1}
- increment = -1
- else:
- raise Exception # XXX
-
- # XXX
- if offset != 0:
- raise NotImplementedError
-
- self._cells = []
- for i in xrange(self.grid.size):
- self._cells.append(ref(self.grid.cell(coords['row'], coords['column'])))
- coords['row'] += 1
- coords['column'] += increment