Exemple #1
0
func BenchmarkBacktrack2(b *testing.B) {
	board, err := puzzle.New([]byte(testInput2))
	if err != nil {
		log.Fatalln(err)
	}

	benchmarkBacktrack(board, b)
}
Exemple #2
0
func BenchmarkDLX5(b *testing.B) {
	board, err := puzzle.New([]byte(testInput5))
	if err != nil {
		log.Fatalln(err)
	}

	benchmarkDLX(board, b)
}
Exemple #3
0
func TestCoverEmptyBoard(t *testing.T) {
	board, err := puzzle.New([]byte(emptyBoard))
	assert.NotNil(t, board)
	assert.NoError(t, err)

	baseCover := baseCover()
	cover := exactCover(board)

	// Since we haven't introduced any new constraints (empty board) except for
	// the basic ones the exact cover should equal the base cover
	for i := range baseCover {
		for j := range baseCover[i] {
			assert.Equal(t, cover[i][j], baseCover[i][j])
		}
	}
}
Exemple #4
0
func TestSolvers(t *testing.T) {
	var tests = []struct {
		input       string
		shouldSolve bool
	}{
		{testInput1, true},
		{testInput2, true},
		{testInput3, false},
		{testInput4, true},
		{testInput5, true},
	}

	for _, test := range tests {
		b, err := puzzle.New([]byte(test.input))
		assert.NoError(t, err)
		assert.NotNil(t, b)

		for _, solver := range buildSolvers(b) {
			solvedBoard := solver.Solve()
			assert.Equal(t, test.shouldSolve, solvedBoard.Solved())
		}
	}
}
Exemple #5
0
func TestCoverSolvedBoard(t *testing.T) {
	board, err := puzzle.New([]byte(solvedBoard))
	assert.NotNil(t, board)
	assert.NoError(t, err)

	cover := exactCover(board)

	// For each cell = N (N in [1,9]) all arrays in the cover matrix at the cells
	// row/col should be all zeroes except for the Nth array.
	for i := 0; i < size; i++ {
		for j := 0; j < size; j++ {
			n := board.ValueAt(i, j)
			for num := 0; num < size; num++ {
				if num != n-1 {
					arr := cover[index(i, j, num)]
					for _, v := range arr {
						assert.Equal(t, 0, v)
					}
				}
			}
		}
	}
}
Exemple #6
0
func main() {
	flag.StringVar(
		&generateFlag,
		"generate",
		"",
		"Generate a Sudoku board, accepts inputs: 'easy', 'medium' 'hard'",
	)
	flag.BoolVar(
		&printDifficuly,
		"print-difficulty",
		false,
		"Prints the difficulty of the input board",
	)
	flag.Parse()

	// Generate a Sudoku board and print it to stdout
	if len(generateFlag) > 0 {
		for {
			// generate a random board
			board, err := puzzle.Generate(generateFlag)
			if err != nil {
				log.Fatalln(err)
			}

			// make sure it can be solved
			// the backtrack algorithm is used to solve the board since it's
			// faster (in most cases) than DLX to detect unsolvable boards
			solvedBoard := backtrack.NewSolver(board).Solve()
			if solvedBoard.Solved() {
				fmt.Println(strings.Replace(board.String(), "0", "_", -1))
				return
			}
		}
	}

	// Read Sudoku board from stdin
	b, err := ioutil.ReadAll(bufio.NewReader(os.Stdin))
	if err != nil {
		log.Fatalln(err)
	}

	// Build the board
	board, err := puzzle.New(b)
	if err != nil {
		log.Fatalln(err)
	}

	// Just print the difficulty of the board if the caller asks for it
	if printDifficuly {
		fmt.Println(board.Difficulty())
		return
	}

	// Solve the board
	dlx := dlx.NewSolver(board)
	solvedBoard := dlx.Solve()
	if !solvedBoard.Solved() {
		log.Fatalln(errUnsolvable)
	}

	fmt.Println(solvedBoard)
}