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; } } } }
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); } } }
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)); }
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); }