private void SearchRec(DomainStore dstore, Sudoku sudoku) { // Select the sudoku cell with the smallest domain and try to fill it first Field f = dstore.GetFieldWithSmallestDomain(); if (f == null) { // There's no cell with a domain size > 1 left, the sudoku is filled completely dstore.UpdateSudoku(sudoku); return; } // Try to solve the sudoku with every possible value of the cell's domain HashSet <int> domain = dstore.GetDomain(f); foreach (int digit in domain) { DomainStore dstoreClone = new(dstore); dstoreClone.SetDomain(f, new HashSet <int>() { digit }); Search(dstoreClone, sudoku); if (sudoku.IsSolved()) { return; } else { // Prune this try and take a step back dstore.UpdateSudoku(sudoku); } } }
private bool Eliminate(DomainStore dstore, IEnumerable <Field> fields) { bool domainsHaveChanged = false; // Go through the cells and remeber the digits you see HashSet <int> seenDigits = new(); foreach (Field f in fields) { if (dstore.GetDomainSize(f) == 1) { HashSet <int> domain = dstore.GetDomain(f); foreach (int digit in domain) // Workaround to access first HashSet value quickly { seenDigits.Add(digit); break; } } } // Now, go through the cells again and update each cell's domain considering the digits you saw in the other cells foreach (Field f in fields) { // If a cells's domain has just a single digit left, it does not have to be changed anymore if (dstore.GetDomainSize(f) == 1) { continue; } HashSet <int> domain = dstore.GetDomain(f); HashSet <int> impossibleDigits = new(seenDigits); HashSet <int> subtraction = Util.Subtract(domain, impossibleDigits); // Prune this try if no digit can't be assigned to the cell if (subtraction.Count == 0) { return(false); } // If a cell's domain has to be updated based on the seen digits, do it and note that there was a change if (!domain.SetEquals(subtraction)) { domainsHaveChanged = true; dstore.SetDomain(f, subtraction); } } return(domainsHaveChanged); }
public DomainStore(DomainStore dstore) { InitFieldsByDomainSize(); for (int x = 0; x < Sudoku.Size; x++) { for (int y = 0; y < Sudoku.Size; y++) { SetDomain(x, y, dstore.GetDomain(x, y)); } } }