//Returns the minimal puzzle corresponding to this one public Puzzle findMinimalPuzzle() { Boolean isSolutionUnique = this.isSolutionUnique(); //If this puzzle is already non-unique, just exit if (!isSolutionUnique) { System.Console.WriteLine("This isn't unique!"); return(null); } //Tracks a list of potential candidates. i.e. the list of nodes the current node connects to List <Puzzle> listOfCandidates = new List <Puzzle>(); //Represents the current node Puzzle initialPuzzle = new Puzzle(); for (int i = 0; i < 9; i++) { for (int j = 0; j < 9; j++) { initialPuzzle.values[i, j] = this.values[i, j]; } } //Initially, the only node we see is the beginning puzzle listOfCandidates.Add(initialPuzzle); do { //Main logic loop int len = listOfCandidates.Count; for (int i = 0; i < len; i++) { //listOfCandidates.Count is constantly decreasing in length, so accessing listOfCandidates.ElementAt(i) is dangerous if (i >= listOfCandidates.Count) { break; } Puzzle candidate = listOfCandidates.ElementAt(i); for (int y = 0; y < 9; y++) { for (int x = 0; x < 9; x++) { //Check every location on the puzzle we're looking at to see if we can reduce it without making it non-unique Puzzle nextPuzzle = candidate.findReducedPuzzle(x, y); if (nextPuzzle != null) { if (!nextPuzzle.isContained(listOfCandidates)) { //If we found a reduced non-unique non-duplicate version of the current puzzle, then add it to the list of candidates listOfCandidates.Add(nextPuzzle); } } } } if (listOfCandidates.Count > 1) { //Now we've added every node that this node connects to that is farther from the root //(i.e. has less numbers given),so we don't need this node anymore listOfCandidates.Remove(candidate); } //We're done with that candidate, move on to the next one in listOfCandidates } //We went through all the elements in listOfCandidates from before, but now that list has changed. // -If there's more than one candidate puzzle left, then re-execute the for loop with the remaining candidates // -If there's only one candidate puzzle left, exit and return that. It lasted through the most removals // of numbers without being non-unique, so it must be the minimal puzzle } while (!(listOfCandidates.Count == 1 && listOfCandidates.ElementAt(0).isSolutionUnique())); return(listOfCandidates.ElementAt(0)); }