def _split_groups(self): """ Split groups where possible. A group of size :math:`n` can be split if there is a subgroup of size :math:`0 < k < n` cells in this group, such that these cells have the same :math:`k` possible symbols. In this case, this group can be considered as two different groups. The subgroup with a possible alphabet of the :math:`k` symbols, and the complementary subgroup. :return: ``True`` iff a change to the board was done. :rtype: bool """ changed = False possibles_to_group_to_cells = defaultdict(lambda: defaultdict(set)) for cell in self._iter_empty_cells(): group_to_symbols = possibles_to_group_to_cells[frozenset(cell.get_possible_symbols())] for group in cell.iterate_groups(): group_to_symbols[group].add(cell) # possibles_to_group_to_cells[possible_symbols, group].add(cell) for possible_symbols, group_to_symbols in possibles_to_group_to_cells.iteritems(): for group, cells in group_to_symbols.iteritems(): if len(possible_symbols) == len(cells) and len(cells) != len(group.cells): new_group = CellGroup(cells) self._groups.append(new_group) new_group.remove_as_subgroup(self._groups) changed = True break else: continue break return changed
def test_cell_group_is_valid_partially_empty_valid(alphabet10): cells = [Cell(0, y, alphabet10) for y in xrange(10)] group = CellGroup(set(cells)) cells[0].set_symbol('0') cells[1].set_symbol('1') assert group.is_valid()
def test_cell_group_contains_cells_false_addition(alphabet10): cells = set([Cell(0, y, alphabet10) for y in xrange(10)]) group = CellGroup(set(cells)) cells.add(Cell(1, 0, alphabet10)) assert not group.contains_cells(cells)
def test_cell_group_contains_cells_false(alphabet10): cells = [Cell(0, y, alphabet10) for y in xrange(10)] group = CellGroup(set(cells)) assert not group.contains_cells(set([Cell(x, 0, alphabet10) for x in xrange(10)]))
def test_cell_group_contains_cells_true_part(alphabet10): cells = [Cell(0, y, alphabet10) for y in xrange(10)] group = CellGroup(set(cells)) assert group.contains_cells(set(cells[2:5]))
def test_cell_group_contains_cells_true_all(alphabet10): cells = set([Cell(0, y, alphabet10) for y in xrange(10)]) group = CellGroup(set(cells)) assert group.contains_cells(cells)
def test_cell_group_is_valid_empty_cells(alphabet10): cells = [Cell(0, y, alphabet10) for y in xrange(10)] group = CellGroup(set(cells)) assert group.is_valid()