Example #1
0
 /// <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 IRuleKeeper CopyWithNewReferences(
     IReadOnlyPuzzleWithMutablePossibleValues?puzzle)
 {
     Debug.Assert((puzzle is null && _puzzle is null) || puzzle?.Size == _puzzle?.Size,
                  $"Puzzle size ({puzzle?.Size}) must match current rule keeper size ({_puzzle?.Size})");
     return(new StandardRuleKeeper(this, puzzle));
 }
 /// <inheritdoc/>
 public bool TryInitFor(IReadOnlyPuzzleWithMutablePossibleValues puzzle)
 {
     _boxSize = Boxes.IntSquareRoot(puzzle.Size);
     _puzzle  = puzzle;
     _helper  = new UniqueInXHelper(puzzle);
     return(true);
 }
 private StandardRuleKeeper(
     StandardRuleKeeper existing, IReadOnlyPuzzleWithMutablePossibleValues?puzzle) : this()
 {
     _boxSize           = existing._boxSize;
     _unsetRowValues    = existing._unsetRowValues?.AsSpan().ToArray();
     _unsetColumnValues = existing._unsetColumnValues?.AsSpan().ToArray();
     _unsetBoxValues    = existing._unsetBoxValues?.AsSpan().ToArray();
     _puzzle            = puzzle;
 }
Example #5
0
 private DynamicRuleKeeper(DynamicRuleKeeper existing, IReadOnlyPuzzleWithMutablePossibleValues?puzzle)
 {
     _rules = new IRule[existing._rules.Length];
     for (int i = 0; i < _rules.Length; ++i)
     {
         _rules[i] = existing._rules[i].CopyWithNewReference(puzzle);
     }
     _puzzle       = puzzle;
     _coordTracker = puzzle is null ? null : new CoordinateTracker(puzzle.Size);
 }
 private UniqueInColumnHeuristic(
     UniqueInColumnHeuristic existing,
     IReadOnlyPuzzleWithMutablePossibleValues?puzzle,
     IMissingColumnValuesTracker rule)
 {
     _columnTracker = rule;
     _puzzle        = puzzle;
     if (existing._helper is not null &&
         puzzle is not null)
     {
         _helper = existing._helper.CopyWithNewReference(puzzle);
     }
 }
 private UniqueInBoxHeuristic(
     UniqueInBoxHeuristic existing,
     IReadOnlyPuzzleWithMutablePossibleValues?puzzle,
     IMissingBoxValuesTracker boxTracker)
 {
     _boxTracker = boxTracker;
     _boxSize    = existing._boxSize;
     _puzzle     = puzzle;
     if (puzzle is not null && existing._helper is not null)
     {
         _helper = existing._helper.CopyWithNewReference(puzzle);
     }
 }
Example #8
0
 private UniqueInRowHeuristic(
     UniqueInRowHeuristic existing,
     IReadOnlyPuzzleWithMutablePossibleValues?puzzle,
     IMissingRowValuesTracker tracker)
 {
     _rowTracker = tracker;
     _puzzle     = puzzle;
     if (existing._helper is not null &&
         puzzle is not null)
     {
         _helper = existing._helper.CopyWithNewReference(puzzle);
     }
 }
Example #9
0
 private StandardHeuristic(
     StandardHeuristic existing,
     IReadOnlyPuzzleWithMutablePossibleValues?puzzle,
     ReadOnlySpan <IRule> rules)
 {
     _rowHeuristic = (UniqueInRowHeuristic)existing._rowHeuristic.CopyWithNewReferences(
         puzzle, rules);
     _columnHeuristic = (UniqueInColumnHeuristic)existing._columnHeuristic
                        .CopyWithNewReferences(puzzle, rules);
     _boxHeuristic = (UniqueInBoxHeuristic)existing._boxHeuristic.CopyWithNewReferences(
         puzzle, rules);
     _numHeuristicsRan = new Stack <int>(existing._numHeuristicsRan);
 }
Example #10
0
        /// <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);
        }
Example #11
0
        /// <summary>
        /// Creates a deep copy of this heuristic. Requires <c>rules</c> to contain an
        /// <see cref="IMissingRowValuesTracker"/>.
        /// </summary>
        public IHeuristic CopyWithNewReferences(
            IReadOnlyPuzzleWithMutablePossibleValues?puzzle, ReadOnlySpan <IRule> rules)
        {
            IMissingRowValuesTracker?rowValuesTracker = null;

            foreach (var rule in rules)
            {
                if (rule is IMissingRowValuesTracker foundRule)
                {
                    rowValuesTracker = foundRule;
                }
            }
            if (rowValuesTracker is null)
            {
                throw new ArgumentException($"{nameof(rules)} must include an {nameof(IMissingRowValuesTracker)}.");
            }
            return(new UniqueInRowHeuristic(this, puzzle, rowValuesTracker));
        }
Example #12
0
 /// <inheritdoc/>
 public IRuleKeeper CopyWithNewReferences(IReadOnlyPuzzleWithMutablePossibleValues?puzzle)
 {
     return(new DynamicRuleKeeper(this, puzzle));
 }
 /// <inheritdoc/>
 public bool TryInitFor(IReadOnlyPuzzleWithMutablePossibleValues puzzle)
 {
     _puzzle = puzzle;
     _helper = new UniqueInXHelper(puzzle);
     return(true);
 }
Example #14
0
 /// <summary>
 /// Creates a deep copy of this heuristic. Requires <c>rules</c> to contain an
 /// <see cref="IMissingBoxValuesTracker"/>, an <see cref="IMissingColumnValuesTracker"/>,
 /// and an <see cref="IMissingRowValuesTracker"/>.
 /// </summary>
 public IHeuristic CopyWithNewReferences(
     IReadOnlyPuzzleWithMutablePossibleValues?puzzle,
     ReadOnlySpan <IRule> rules) => new StandardHeuristic(this, puzzle, rules);