Exemplo n.º 1
0
        private void FindTuple(MutablePuzzle puzzle, RegionQueue regions, Region region, SudokuValues placedDigits)
        {
            var combinations = Helpers.GetCombinationIndices(Puzzle.LineLength, _size);

            for (int i = 0; i < combinations.Length; i++)
            {
                var comb = combinations[i];

                if (placedDigits.HasAnyOptions(comb))
                {
                    // skip any tuples that include placed digits
                    continue;
                }

                var positions = region.GetPositions(comb);

                if (positions.GetOptionCount() != _size)
                {
                    // these digits are placeable in more than tupleSize spots, so not hidden tuple
                    continue;
                }

                // we found a hidden tuple!
                var options = ArrayPool <int> .Shared.Rent(Puzzle.LineLength);

                var count      = positions.CopyIndices(options);
                var opposite   = comb.Invert();
                var anyChanged = false;

                for (var index = 0; index < count; index++)
                {
                    var cell = region[options[index]];

                    if (!cell.IsSingle && cell.HasAnyOptions(opposite))
                    {
                        var update = region.RemoveOptions(options[index], opposite);
                        puzzle.RemoveOptions(update);
                        anyChanged = true;

                        regions.Enqueue(RegionType.Row, update.Coordinate.Row);
                        regions.Enqueue(RegionType.Column, update.Coordinate.Column);
                        regions.Enqueue(RegionType.Box, update.Coordinate.Box);
                    }
                }

                ArrayPool <int> .Shared.Return(options);

                if (anyChanged)
                {
#if DEBUG
                    Program.Debugger.AddAction($"Hidden {comb} tuple in {region}");
#endif
                    return;
                }
            }
        }
Exemplo n.º 2
0
        private void FindTuple(MutablePuzzle puzzle, RegionQueue regions, Region region, SudokuValues placedDigits)
        {
            var combinations = Helpers.GetCombinationIndices(Puzzle.LineLength, _size);

            for (int j = 0; j < combinations.Length; j++)
            {
                var comb = combinations[j];

                if (placedDigits.HasAnyOptions(comb))
                {
                    // skip any tuples that include placed digits
                    continue;
                }

                var indices = ArrayPool <int> .Shared.Rent(_size);

                var count          = comb.CopyIndices(indices);
                var possibleValues = SudokuValues.None;

                for (int i = 0; i < count; i++)
                {
                    var cell = region[indices[i]];
                    possibleValues = possibleValues.AddOptions(cell);
                }

                ArrayPool <int> .Shared.Return(indices);

                var optionsCount = possibleValues.GetOptionCount();

                if (optionsCount == _size)
                {
                    // we found a tuple!

                    for (var i = 0; i < Puzzle.LineLength; i++)
                    {
                        var otherCell = region[i];

                        if (otherCell.IsSingle)
                        {
                            continue;
                        }

                        if (!otherCell.HasAnyOptions(possibleValues))
                        {
                            continue;
                        }

                        if (comb.HasAnyOptions(SudokuValues.FromIndex(i)))
                        {
                            continue;
                        }

                        var newCell = region.RemoveOptions(i, possibleValues);
                        puzzle.RemoveOptions(newCell);

                        regions.Enqueue(RegionType.Row, newCell.Coordinate.Row);
                        regions.Enqueue(RegionType.Column, newCell.Coordinate.Column);
                        regions.Enqueue(RegionType.Box, newCell.Coordinate.Box);
#if DEBUG
                        Program.Debugger.AddAction($"{possibleValues} tuple in {region}.");
#endif
                    }
                }
            }
        }