private void ScanRegion(RegionQueue regions, MutablePuzzle puzzle, Region region)
        {
            var placedDigits = region.GetPlacedDigits();

            for (int i = 1; i <= Puzzle.LineLength; i++)
            {
                var digit = SudokuValues.FromHumanValue(i);

                if (placedDigits.HasAnyOptions(digit))
                {
                    continue;
                }

                var positions = region.GetPositions(digit);

                if (positions.IsSingle)
                {
                    var index  = positions.ToIndex();
                    var coords = region.GetCoordinate(index);

                    var update = new CellUpdate(digit.Invert(), coords);
                    puzzle.RemoveOptions(update);

                    regions.Enqueue(RegionType.Row, coords.Row);
                    regions.Enqueue(RegionType.Column, coords.Column);
                    regions.Enqueue(RegionType.Box, coords.Box);
                }
            }
        }
Exemple #2
0
 private (SudokuValues row, SudokuValues col, SudokuValues box) GetValues(int rowVal, int colVal, int boxVal)
 {
     return(
         SudokuValues.FromHumanValue(rowVal),
         SudokuValues.FromHumanValue(colVal),
         SudokuValues.FromHumanValue(boxVal)
         );
 }
        public void Apply(MutablePuzzle puzzle, RegionQueue changedRegions)
        {
            if (++depth > 10)
            {
                return;
            }

            while (changedRegions.TryDequeue(puzzle, out var region))
            {
                for (int i = 0; i < Puzzle.LineLength; i++)
                {
                    var value  = region[i];
                    var coords = region.GetCoordinate(i);

                    if (value.GetOptionCount() != 2)
                    {
                        continue;
                    }

                    // if there are are only 2 bits set, bitwise and
                    // with the value - 1 will return the highest option
                    var highestValue = new SudokuValues(value.Values & (value.Values - 1));

#if DEBUG
                    Program.Debugger.AddAction($"Attempting {highestValue.Invert().Intersect(value)} in {coords}");
#endif

                    var oldSolver = _solver;
                    var changeset = new SingleCellChangeSet(new CellUpdate(highestValue, coords));
                    var newSolver = new Solver(changeset, _solver);

                    _solver = newSolver;

                    var(result, _) = newSolver.Solve();

                    _solver = oldSolver;

#if DEBUG
                    Program.Debugger.AddAction($"Result: {result}");
#endif

                    switch (result)
                    {
                    case SolveResult.Success:
                        puzzle.Absorb(newSolver.Puzzle);
                        return;

                    case SolveResult.Invalid:
                        // we picked the wrong digit
                        puzzle.RemoveOptions(new CellUpdate(highestValue.Invert(), coords));
                        return;
                    }
                }
            }
        }
Exemple #4
0
 private static void PrintFieldPart(SudokuValues values, int part)
 {
     for (int v = part; v < part + 3; v++)
         Console.Write(values.Contains((byte)v) ? (v + 1).ToString(CultureInfo.InvariantCulture) : " ");
 }