1 from __future__
import division
3 from weakref
import ref
5 class CellConstraint(object):
6 """Represents any group of cells in a grid that cannot repeat a digit."""
10 # NOTE: _cells is a list of refs; _grid is a ref
12 cells
= property(lambda self
: [ x() for x
in self
._cells
])
13 grid
= property(lambda self
: self
._grid())
16 # XXX inherited __init__ to init _grid/_cells
18 def find_value(self
, value
):
19 """Returns the cells that can be a specific value."""
21 for cell
in self
.cells
:
22 if value
in cell
._values
:
23 possible_cells
.append(cell
)
25 if len(possible_cells
) == 0:
30 def resolve_uniques(self
):
31 for value
in xrange(self
.grid
._size
):
32 # XXX cache values that are taken care of
33 possible_cells
= self
.find_value(value
)
35 if len(possible_cells
) > 1:
39 target_cell
= possible_cells
[0]
40 if target_cell
.solved
:
42 # XXX this is what cache is for
45 # Only cell in the group that can be value
46 target_cell
.set(value
)
49 class Box(CellConstraint
):
50 def _get_box_row(self
):
51 return self
._pos
// self
.grid
._box_width
52 box_row
= property(_get_box_row
)
54 def _get_box_column(self
):
55 return self
._pos % self
.grid
._box_height
56 box_column
= property(_get_box_column
)
58 def __init__(self
, grid
, position
):
59 self
._grid
= ref(grid
)
63 for row
in xrange(self
.grid
._box_height
):
64 for col
in xrange(self
.grid
._box_width
):
65 cell_row
= row
+ self
.box_row
* self
.grid
._box_height
66 cell_col
= col
+ self
.box_column
* self
.grid
._box_width
67 self
._cells
.append(ref(self
.grid
.cell(cell_row
, cell_col
)))
70 class Row(CellConstraint
):
71 def __init__(self
, grid
, position
):
72 self
._grid
= ref(grid
)
76 for col
in xrange(self
.grid
._size
):
77 self
._cells
.append(ref(self
.grid
.cell(self
._pos
, col
)))
79 class Column(CellConstraint
):
80 def __init__(self
, grid
, position
):
81 self
._grid
= ref(grid
)
85 for row
in xrange(self
.grid
._size
):
86 self
._cells
.append(ref(self
.grid
.cell(row
, self
._pos
)))
88 class Diagonal(CellConstraint
):
89 def __init__(self
, grid
, direction
='down', offset
=0):
90 self
._grid
= ref(grid
)
91 self
._direction
= direction
94 if direction
== 'down':
95 coords
= {'row': 0, 'column': 0}
97 elif direction
== 'up':
98 coords
= {'row': 0, 'column': grid
.size
- 1}
101 raise Exception # XXX
105 raise NotImplementedError
108 for i
in xrange(self
.grid
.size
):
109 self
._cells
.append(ref(self
.grid
.cell(coords
['row'], coords
['column'])))
111 coords
['column'] += increment