Skip to content

Commit

Permalink
Merge 743e5df into 395e321
Browse files Browse the repository at this point in the history
  • Loading branch information
vaskoz committed Jan 11, 2019
2 parents 395e321 + 743e5df commit f0d1383
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 0 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ problems from
* [Day 61](https://github.com/vaskoz/dailycodingproblem-go/issues/132)
* [Day 62](https://github.com/vaskoz/dailycodingproblem-go/issues/134)
* [Day 63](https://github.com/vaskoz/dailycodingproblem-go/issues/136)
* [Day 64](https://github.com/vaskoz/dailycodingproblem-go/issues/138)
* [Day 65](https://github.com/vaskoz/dailycodingproblem-go/issues/139)
* [Day 66](https://github.com/vaskoz/dailycodingproblem-go/issues/141)
* [Day 67](https://github.com/vaskoz/dailycodingproblem-go/issues/143)
Expand Down
49 changes: 49 additions & 0 deletions day64/problem.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package day64

// KnightsTourCountBacktracking returns the number of tours
// on a NxN chessboard. The only argument is N.
// Operates in exponential time. O(8^(N^2)).
func KnightsTourCountBacktracking(N int) int {
var count int
for i := 0; i < N; i++ {
for j := 0; j < N; j++ {
board := make([][]bool, N)
for x := range board {
board[x] = make([]bool, N)
}
board[i][j] = true
count += knightsTourCounter(N, board, [][]int{{i, j}})
}
}
return count
}

func knightsTourCounter(N int, board [][]bool, tour [][]int) int {
if len(tour) == N*N {
return 1
}
var count int
last := tour[len(tour)-1]
r, c := last[0], last[1]
for _, move := range validMoves(board, r, c, N) {
board[move[0]][move[1]] = true
count += knightsTourCounter(N, board, append(tour, move))
board[move[0]][move[1]] = false
}
return count
}

func validMoves(board [][]bool, r, c, N int) [][]int {
moves := make([][]int, 0, 8)
deltas := [][]int{{2, 1}, {1, 2}, {1, -2}, {-2, 1}, {-1, 2}, {2, -1}, {-1, -2}, {-2, -1}}
for _, delta := range deltas {
if isValidMove(board, N, r+delta[0], c+delta[1]) {
moves = append(moves, []int{r + delta[0], c + delta[1]})
}
}
return moves
}

func isValidMove(board [][]bool, n, r, c int) bool {
return 0 <= r && r < n && 0 <= c && c < n && !board[r][c]
}
28 changes: 28 additions & 0 deletions day64/problem_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package day64

import "testing"

var testcases = []struct {
N, Tours int
}{
{1, 1},
{2, 0},
{3, 0},
{4, 0},
// {5, 1728}, // uncommenting takes 94.08s user 1.04s system 104% cpu 1:31.42 total
}

func TestKnightsTourCountBacktracking(t *testing.T) {
t.Parallel()
for _, tc := range testcases {
if result := KnightsTourCountBacktracking(tc.N); result != tc.Tours {
t.Errorf("For N=%d expected %d got %d", tc.N, tc.Tours, result)
}
}
}

func BenchmarkKnightsTourCountBacktracking(b *testing.B) {
for i := 0; i < b.N; i++ {
KnightsTourCountBacktracking(3)
}
}

0 comments on commit f0d1383

Please sign in to comment.