Exemple #1
0
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
}