Пример #1
0
func scanCage(s *domain.Sudoku) (bool, error) {
	rows := domain.BOARD_ROWS / 3
	cols := domain.BOARD_COLS / 3

	for i := 0; i < rows; i++ {
		for j := 0; j < cols; j++ {
			count := make([]int, 9)
			lastRow := make([]int, 9)
			lastCol := make([]int, 9)

			for row := i * 3; row < i*3+3; row++ {
				for col := j * 3; col < j*3+3; col++ {
					for n, mask := range AV_LIST {
						if s.Available[row*domain.BOARD_COLS+col]&mask == mask {
							count[n]++
							lastRow[n] = row
							lastCol[n] = col
						}
					}
				}
			}

			// A hidden single in the cage has been found, solve it
			for j, c := range count {
				if c != 1 {
					continue
				}

				if s.Answer[lastRow[j]*domain.BOARD_COLS+lastCol[j]] != 0 {
					continue
				}

				fmt.Printf(" * Solving hidden single [cage]: %dx%d (%d)\n", lastCol[j], lastRow[j], j+1)

				if err := s.SolveCell(lastRow[j], lastCol[j], uint(j+1)); err != nil {
					return false, err
				}

				return true, nil
			}
		}
	}

	return false, nil
}
Пример #2
0
func scanCol(s *domain.Sudoku) (bool, error) {
	for i := 0; i < domain.BOARD_COLS; i++ {
		count := make([]int, 9)
		lastRow := make([]int, 9)

		// Scan the rows
		for j := 0; j < domain.BOARD_ROWS; j++ {
			for n, mask := range AV_LIST {
				if s.Available[j*domain.BOARD_COLS+i]&mask == mask {
					count[n]++
					lastRow[n] = j
				}
			}
		}

		// A hidden single in the col has been found, solve it
		for j, c := range count {
			if c != 1 {
				continue
			}

			if s.Answer[lastRow[j]*domain.BOARD_COLS+i] != 0 {
				continue
			}

			fmt.Printf(" * Solving hidden single [col]: %dx%d (%d)\n", i, lastRow[j], j+1)

			if err := s.SolveCell(lastRow[j], i, uint(j+1)); err != nil {
				return false, err
			}

			return true, nil
		}
	}

	return false, nil
}
Пример #3
0
func solve(s *domain.Sudoku) error {
	// Always print the final sudoku before exiting
	defer s.Print()

	// Apply the cages combinations read from the data file
	if err := strategies.KillerCombinations(s); err != nil {
		return err
	}

	// List of strategies we can apply, ordered from simpler and quicker to
	// more complex and slower
	slist := []Strategy{
		strategies.HiddenSingles,
		strategies.NakedPairs,
	}

	for {
		// Check if the puzzle is solved
		if s.Solved() {
			return nil
		}

		// Check for solved squares
		if done, err := s.SolvedSquares(); err != nil {
			return err
		} else if done {
			continue
		}

		// Apply all the strategies to the sudoku
		// until one modifies the content
		i := 0
		for _, strat := range slist {
			i += 1
			if done, err := strat(s); err != nil {
				return err
			} else if done {
				i -= 1
				break
			}
		}

		// The puzzle can't be solved
		if i == len(slist) {
			break
		}
	}

	fmt.Println("ERROR: No more strategies to try. Puzzle unsolvable")
	return nil
	//return domain.NewErrorf("no more strategies to try. puzzle unsolvable")
}