Beispiel #1
0
        public void Solve()
        {
            BasicSolve();
            if (IsLegal && !IsSolved)
            {
                var undeterminedCells =
                    MatrixIterator
                    .Where(cell => !cell.IsDetermined);

                SudokuCell speculationTarget = undeterminedCells
                                               .First(cell => cell.Candidates.Count ==
                                                      undeterminedCells.Min(c => c.Candidates.Count));

                Random rng = new Random();
                var    shuffledCandidates = speculationTarget.Candidates
                                            .OrderBy(c => rng.Next());
                foreach (int candidate in shuffledCandidates)
                {
                    SudokuBoard speculativeBoard = new SudokuBoard(this);
                    speculativeBoard.SetCell(
                        cellRow: speculationTarget.Row,
                        cellColumn: speculationTarget.Column,
                        valueToSet: candidate);

                    speculativeBoard.Solve();
                    if (speculativeBoard.IsLegal && speculativeBoard.IsSolved)
                    {
                        this.Copy(speculativeBoard);
                        return;
                    }
                }
            }
        }
Beispiel #2
0
        public async Task ParallelSolve(int branchingDepth = -1)
        {
            if (branchingDepth == 0)
            {
                Solve();
                return;
            }

            BasicSolve();
            if (IsLegal && !IsSolved)
            {
                var undeterminedCells =
                    MatrixIterator
                    .Where(cell => !cell.IsDetermined);

                SudokuCell speculationTarget = undeterminedCells
                                               .First(cell => cell.Candidates.Count ==
                                                      undeterminedCells.Min(c => c.Candidates.Count));

                var tokenSource = new CancellationTokenSource();
                List <Task <SudokuBoard> > speculationTasks = new List <Task <SudokuBoard> >();
                foreach (int candidate in speculationTarget.Candidates)
                {
                    SudokuBoard speculativeBoard = new SudokuBoard(this);
                    speculativeBoard.SetCell(
                        cellRow: speculationTarget.Row,
                        cellColumn: speculationTarget.Column,
                        valueToSet: candidate);


                    var token = tokenSource.Token;
                    speculationTasks.Add(
                        Task.Factory.StartNew(() =>
                    {
                        speculativeBoard
                        .ParallelSolve(branchingDepth > 0 ? branchingDepth - 1 : branchingDepth)
                        .Wait(token);
                        return(speculativeBoard);
                    },
                                              token)
                        );
                }

                while (speculationTasks.Count > 0)
                {
                    Task <SudokuBoard> completedTask = await Task.WhenAny(speculationTasks);

                    SudokuBoard speculativeBoard = completedTask.Result;
                    if (speculativeBoard.IsLegal && speculativeBoard.IsSolved)
                    {
                        tokenSource.Cancel();
                        this.Copy(speculativeBoard);
                        return;
                    }
                    speculationTasks.Remove(completedTask);
                }
            }
        }
Beispiel #3
0
        public void RecomputeCandidates()
        {
            MatrixIterator
            .Where(cell => !cell.IsDetermined)
            .ToList()
            .ForEach(cell => cell.Clear());

            MatrixIterator
            .Where(cell => cell.IsDetermined)
            .ToList()
            .ForEach(cell => UpdateBoardCandidates(
                         sourceRow: cell.Row,
                         sourceColumn: cell.Column,
                         valueToRemove: (int)cell.Value));
        }
Beispiel #4
0
        public int SetNakedCandidateCells()
        {
            int nCellsSet = 0;

            MatrixIterator
            .Where(cell => cell.HasNakedCandidate())
            .ToList()
            .ForEach(
                cell =>
            {
                if (cell.Candidates.Count == 1)
                {
                    SetCell(
                        cellRow: cell.Row,
                        cellColumn: cell.Column,
                        valueToSet: cell.Candidates.First());
                    nCellsSet++;
                }
            });

            return(nCellsSet);
        }