func processSquare(i int, working working) working { square := working[i] square.checkValues(grid.IndicesForRow(i), working) square.checkValues(grid.IndicesForColumn(i), working) square.checkValues(grid.IndicesForSub(i), working) if working[i].Value != square.Value { working[i] = square for _, index := range grid.IndicesForRow(i) { if working[index].Value == 0 { working = processSquare(index, working) } } for _, index := range grid.IndicesForColumn(i) { if working[index].Value == 0 { working = processSquare(index, working) } } for _, index := range grid.IndicesForSub(i) { if working[index].Value == 0 { working = processSquare(index, working) } } } return working }
func (b multiBacktrackingSolver) Solve(given Grid) ([]Grid, error) { var puzzle [81]backtrackSquare for i, value := range given { puzzle[i] = backtrackSquare{value: value, initial: value != 0} } var solutions []Grid forward := true i := 0 for { if puzzle[i].initial { if forward { i++ } else { i-- } } else { forward = true puzzle[i].value++ ok := false if puzzle[i].value > 9 { puzzle[i].value = 0 forward = false i-- } else { ok = checkValues(grid.IndicesForColumn(i), puzzle[i].value, puzzle) if ok { ok = checkValues(grid.IndicesForRow(i), puzzle[i].value, puzzle) } if ok { ok = checkValues(grid.IndicesForSub(i), puzzle[i].value, puzzle) } } if ok { i++ } } if i >= 81 { // Puzzle is done record this solution and go back and find more var ended [81]int for i, square := range puzzle { ended[i] = square.value } solutions = append(solutions, ended) forward = false i-- } if i <= 0 { // Found all the solutions break } } return solutions, nil }
func (b randBacktrackingSolver) Solve(given Grid) (Grid, error) { var puzzle [81]randBacktrackSquare for i, value := range given { puzzle[i] = randBacktrackSquare{ value: value, initial: value != 0, candidates: mixedValues(), candidateIndex: -1} } forward := true for i := 0; i < 81; { if puzzle[i].initial { if forward { i++ } else { i-- } } else { forward = true ok := false puzzle[i].candidateIndex++ if puzzle[i].outOfCandidates() { puzzle[i].candidateIndex = -1 puzzle[i].value = 0 forward = false i-- } else { puzzle[i].value = puzzle[i].nextCandidate() ok = randCheckValues(grid.IndicesForColumn(i), puzzle[i].value, puzzle) if ok { ok = randCheckValues(grid.IndicesForRow(i), puzzle[i].value, puzzle) } if ok { ok = randCheckValues(grid.IndicesForSub(i), puzzle[i].value, puzzle) } } if ok { i++ } } } var ended Grid for i, square := range puzzle { ended[i] = square.value } return ended, nil }
func (b backtrackingSolver) Solve(given Grid) (Grid, error) { var puzzle [81]backtrackSquare for i, value := range given { puzzle[i] = backtrackSquare{value: value, initial: value != 0} } forward := true for i := 0; i < 81; { if puzzle[i].initial { if forward { i++ } else { i-- } } else { forward = true puzzle[i].value++ ok := false if puzzle[i].value > 9 { puzzle[i].value = 0 forward = false i-- } else { ok = checkValues(grid.IndicesForColumn(i), puzzle[i].value, puzzle) if ok { ok = checkValues(grid.IndicesForRow(i), puzzle[i].value, puzzle) } if ok { ok = checkValues(grid.IndicesForSub(i), puzzle[i].value, puzzle) } } if ok { i++ } } if i < 0 { return Grid{}, errors.New("Unsolvable puzzle") } } var ended [81]int for i, square := range puzzle { ended[i] = square.value } return ended, nil }