Beispiel #1
0
        /// <summary>Reduces naked triples.</summary>
        private ReduceResult ReduceNakedTriples(ReduceResult result, SudokuState state)
        {
            if (SkipMethod(SudokuSolverMethods.NakedTriples, result)) { return result; }

            foreach (var singleValue in Puzzle.SingleValues)
            {
                foreach (var region in Puzzle.Regions)
                {
                    var index0 = -1;
                    var index1 = -1;
                    var index2 = -1;

                    var match = singleValue;

                    foreach (var index in region)
                    {
                        var value = state[index];
                        if (!state.IsKnown(index) && (value & match) != SudokuPuzzle.Invalid)
                        {
                            match |= value;

                            /**/ if (index0 == -1) { index0 = index; }
                            else if (index1 == -1) { index1 = index; }
                            else if (index2 == -1) { index2 = index; }
                            else { index2 = -1; break; }
                        }
                    }
                    // We found 3 cells.
                    if (index2 != -1 && SudokuCell.Count(match) == 3)
                    {
                        foreach (var index in region)
                        {
                            if (index != index0 && index != index1 && index != index2)
                            {
                                result |= state.AndMask(index, ~match);
                            }
                        }
                    }
                }
            }
            return result;
        }
Beispiel #2
0
        /// <summary>Reduces hidden singles.</summary>
        /// <remarks>
        /// Very frequently, there is only one candidate for a given row, column or
        /// sub square, but it is hidden among other candidates.
        /// </remarks>
        private ReduceResult ReduceHiddenSingles(ReduceResult result, SudokuState state)
        {
            if (SkipMethod(SudokuSolverMethods.HiddenSingles, result)) { return result; }

            foreach (var region in Puzzle.Regions)
            {
                foreach (var singleValue in Puzzle.SingleValues)
                {
                    var cnt = 0;
                    var found = -1;
                    foreach (var index in region)
                    {
                        var val = state[index];
                        if ((val & singleValue) != SudokuPuzzle.Invalid)
                        {
                            unchecked { cnt++; }
                            if (state.IsKnown(index))
                            {
                                found = -1;
                                break;
                            }
                            else if (cnt == 1)
                            {
                                found = index;
                            }
                        }
                    }
                    if (cnt == 1 && found != -1)
                    {
                        result |= state.AndMask(found, singleValue);
                    }
                    else if (cnt == 0)
                    {
                        return ReduceResult.Inconsistend;
                    }
                }
            }
            return result;
        }
Beispiel #3
0
        /// <summary>Reduces options that should be in the intersection.</summary>
        private ReduceResult ReduceLockedCandidates(ReduceResult result, SudokuState state)
        {
            if (SkipMethod(SudokuSolverMethods.LockedCandidates, result)) { return result; }

            foreach (var region in Puzzle.Regions)
            {
                foreach (var other in region.Intersected)
                {
                    ulong combined = 0;
                    foreach (var index in region)
                    {
                        if (!other.Contains(index))
                        {
                            combined |= state[index];
                        }
                    }
                    // There are options that should be in the intersection.
                    if (combined != Puzzle.Unknown)
                    {
                        foreach (var index in other)
                        {
                            if (!region.Contains(index))
                            {
                                var val = state[index];
                                var nw = val & combined;
                                result |= state.AndMask(index, nw);
                            }
                        }
                    }
                }
            }
            return result;
        }