/// <summary> /// Checks the entire grid for correctness. Slower than IsSolved(). /// </summary> /// <returns></returns> public bool IsCorrect() { bool isCorrect = true; CellSet row, col, subgrid; for (int i = 0; i < PuzzleSize; i++) { row = new CellSet(GetRow(i)); col = new CellSet(GetCol(i)); if (!row.IsCorrect() || !col.IsCorrect()) { isCorrect = false; break; } } for (int i = 0; i < Subgrids.Count; i++) { subgrid = new CellSet(Subgrids[i]); if (!subgrid.IsCorrect()) { isCorrect = false; break; } } Console.WriteLine(($"Puzzle is free of single value conflicts: {isCorrect}")); Console.WriteLine(ToString()); if (Program.solveLogFlag) { //Program.solveLog.Write($"Puzzle is correct: {isCorrect}" + "\n" + ToString()); using (Program.solveLog) { Program.solveLog.Write($"Puzzle is free of single value conflicts: {isCorrect}" + "\n" + ToString()); } } if (Program.finalStateFlag) { using (Program.finalStateFile) { Program.finalStateFile.Write($"Puzzle is free of single value conflicts: {isCorrect}" + "\n" + ToString()); } } return(isCorrect); }
/// <summary> /// Looks at a group of cells and determines if any of the values are only represented once. /// I suspect this is incapable of reaching n > 1 cases, though the concept could be applied in certain cases. /// </summary> /// <param name="cellGroup"></param> /// /// <param name="n"></param> /// <returns></returns> public int ValueCountInference(List <Cell> cellGroup, int n) { int removals = 0; int[] alphabetCount = new int[PuzzleSize]; HashSet <char> matchSet; CellSet cellSet = new CellSet(cellGroup); alphabetCount = cellSet.ValueCount(this); //for each v with v.count = n for (int i = 0; i < alphabetCount.Length; i++) { if (alphabetCount[i] == n) { //add v to new matchlist, hashset matchSet = new HashSet <char>() { AlphabetArr[i] }; //if matchlist.count = n //only runs for n = 1, maybe a hack if (matchSet.Count == n) { //remove values that matchlist does not contain from cells with v in current group for (int j = 0; j < cellGroup.Count; j++) { //this is the list way to check for subset: "!matchlist.Except(cellGroup[j].ValueList).Any()" //This still returns true if matchlist is a proper subset of ValueList if (matchSet.IsProperSubsetOf(cellGroup[j].ValueSet)) { removals += cellGroup[j].OverWriteValueMembers(matchSet); } } } } } return(removals); }
/// <summary> /// Searches for a value only represented once in a group of cells in an unsolved cell. /// This is an simplified application of ValueCountInference() that applies the n = 1 case. /// </summary> /// <param name="cellGroup">The the group of cells being considered.</param> /// <returns>The number of removals.</returns> public int SingleValueCount(CellSet cellGroup) { int removals = 0; int[] alphabetCount = cellGroup.ValueCount(this); //HashSet<char> matchSet; for (int i = 0; i < alphabetCount.Length; i++) { //for each value represented only once if (alphabetCount[i] == 1) { foreach (var cell in cellGroup) { if (!cell.IsSolved() && cell.ValueSet.Contains(AlphabetArr[i])) { cell.OverWriteValueMembers(AlphabetArr[i].ToString()); removals++; } } } } return(removals); }
public int ValueCount2(List <Cell> cellGroup, int n) { int removals = 0; int[] alphabetCount = new int[9]; List <char> matchList; HashSet <char> matchSet; //count instances of each value in a group CellSet cellSet = new CellSet(cellGroup); alphabetCount = cellSet.ValueCount(this); //for each v with v.count = n for (int i = 0; i < alphabetCount.Length; i++) { if (alphabetCount[i] == n) { //add v to new matchlist, hashset matchSet = new HashSet <char>() { AlphabetArr[i] }; //HACK this will get stuck int shareCount = 0; //for each other value (ov) sharing any cell with v for (int j = i + 1; j < AlphabetArr.Length; j++) { if (AlphabetArr[j] == n) { matchSet.Add(AlphabetArr[j]); } for (int k = 0; k < cellGroup.Count; k++) { if (true) { //TODO start here } } } //if ov.count = n //add ov to matchlist if (matchSet.Count == n) { //Remove other values in cells with values that are a superset of matchset, //leaving only matchset values in cells with matchset values for (int j = 0; j < cellGroup.Count; j++) { //this is the list way to check for subset: "!matchlist.Except(cellGroup[j].ValueList).Any()" //This still returns true if matchlist is a proper subset of ValueList if (matchSet.IsProperSubsetOf(cellGroup[j].ValueSet)) { removals += cellGroup[j].OverWriteValueMembers(matchSet); Console.WriteLine($"ValueCount removal at : {cellGroup[j].Row}, {cellGroup[j].Col}"); } } //if cells containing v are in the same row/col (only check for n count <= SubgridRows or SubgridCols) //remove v's of matchlist from intersecting row/col } else { //this is unecessary with the above while statement Console.WriteLine("subset sieve else not implemented"); //Console.ReadLine(); //for each other value (ov) sharing any cell with v //if ov.count = n //add ov to matchlist //if matchlist.count = n //remove values that matchlist does not contain from cells with v in in current group //if cells containing v are in the same row/col (only check for n count <= SubgridRows or SubgridCols) //remove v's of matchlist from intersecting row/col } } } //count instances of each value in a group //for each v with v.count = n //add v to new matchlist //if matchlist.count = n //remove values that matchlist does not contain from cells with v in in current group //if cells containing v are in the same row/col (only check for n count <= SubgridRows or SubgridCols) //remove v's of matchlist from intersecting row/col //else //for each other value (ov) sharing any cell with v //if ov.count = n //add ov to matchlist //if matchlist.count = n //remove values that matchlist does not contain from cells with v in in current group //if cells containing v are in the same row/col (only check for n count <= SubgridRows or SubgridCols) //remove v's of matchlist from intersecting row/col return(removals); }