/// <inheritdoc/> public bool TryInit(IReadOnlyPuzzleWithMutablePossibleValues puzzle) { foreach (IRule r in _rules) { if (!r.TryInit(puzzle, puzzle.UniquePossibleValues)) { return(false); } } foreach (Coordinate c in puzzle.GetUnsetCoords()) { foreach (IRule r in _rules) { puzzle.IntersectPossibleValues(in c, r.GetPossibleValues(in c)); } if (puzzle.GetPossibleValues(in c).IsEmpty) { return(false); } } if (_coordTracker is null || _coordTracker.Size != puzzle.Size) { _coordTracker = new CoordinateTracker(puzzle.Size); } _puzzle = puzzle; return(true); }
/// <inheritdoc/> public bool TryInit(IReadOnlyPuzzleWithMutablePossibleValues puzzle) { int size = puzzle.Size; _puzzle = puzzle; _boxSize = Boxes.IntSquareRoot(puzzle.Size); _unsetRowValues = new BitVector[size]; _unsetRowValues.AsSpan().Fill(_puzzle.UniquePossibleValues); Span <BitVector> possibleValues = _unsetRowValues.AsSpan(); _unsetColumnValues = possibleValues.ToArray(); _unsetBoxValues = possibleValues.ToArray(); int boxIdx; for (int row = 0; row < size; row++) { for (int col = 0; col < size; col++) { boxIdx = Boxes.CalculateBoxIndex(new Coordinate(row, col), _boxSize); int?val = puzzle[row, col]; if (!val.HasValue) { continue; } if (!_unsetRowValues[row].IsBitSet(val.Value) || !_unsetColumnValues[col].IsBitSet(val.Value) || !_unsetBoxValues[boxIdx].IsBitSet(val.Value)) { return(false); } _unsetRowValues[row].UnsetBit(val.Value); _unsetColumnValues[col].UnsetBit(val.Value); _unsetBoxValues[boxIdx].UnsetBit(val.Value); } } foreach (Coordinate c in puzzle.GetUnsetCoords()) { _puzzle.IntersectPossibleValues(in c, _GetPossibleValues(in c)); if (_puzzle.GetPossibleValues(in c).IsEmpty) { return(false); } } return(true); }