Skip to content

Commit 5a63ae6

Browse files
committed
problem038
1 parent eb53b70 commit 5a63ae6

File tree

4 files changed

+110
-0
lines changed

4 files changed

+110
-0
lines changed

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -53,3 +53,4 @@ Number | Difficulty | Asked By | Title
5353
[#35](problem035) | HARD | Google
5454
[#36](problem036) | MEDIUM | Dropbox | Finding the second largest node in BST
5555
[#37](problem037) | EASY | Google | Generating the power set of a set
56+
[#38](problem038) | HARD | Microsoft | Arranging queens without threatening one another

problem038/README.md

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
## Daily Coding Problem: Problem #38 [HARD]
2+
3+
Good morning! Here's your coding interview problem for today.
4+
5+
This problem was asked by Microsoft.
6+
7+
You have an N by N board. Write a function that, given N, returns the number of possible arrangements of the board where N queens can be placed on the board without threatening each other, i.e. no two queens share the same row, column, or diagonal.
8+

problem038/problem038.go

+84
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
package problem038
2+
3+
type chessBoard [][]bool
4+
5+
func newChessBoard(size int) *chessBoard {
6+
board := make(chessBoard, size, size)
7+
for i := range board {
8+
board[i] = make([]bool, size, size)
9+
}
10+
return &board
11+
}
12+
13+
func (thisBoard *chessBoard) hasQueen(row int, column int) bool {
14+
return (*thisBoard)[row][column]
15+
}
16+
17+
func (thisBoard *chessBoard) putQueen(row int, column int) {
18+
(*thisBoard)[row][column] = true
19+
}
20+
21+
func (thisBoard *chessBoard) removeQueen(row int, column int) {
22+
(*thisBoard)[row][column] = false
23+
}
24+
25+
func (thisBoard *chessBoard) isSafe(row int, column int) bool {
26+
onBoard := func(r int, c int) bool {
27+
return r >= 0 && r < len(*thisBoard) && c >= 0 && c < len(*thisBoard)
28+
}
29+
30+
// horizontal check is unnecessary
31+
32+
// vertical
33+
for otherRow := 0; onBoard(otherRow, column); otherRow++ {
34+
if thisBoard.hasQueen(otherRow, column) {
35+
return false
36+
}
37+
}
38+
39+
// diagonal
40+
for otherRow, otherColumn := row, column; onBoard(otherRow, otherColumn); otherRow, otherColumn = otherRow+1, otherColumn+1 {
41+
if thisBoard.hasQueen(otherRow, otherColumn) {
42+
return false
43+
}
44+
}
45+
for otherRow, otherColumn := row, column; onBoard(otherRow, otherColumn); otherRow, otherColumn = otherRow-1, otherColumn-1 {
46+
if thisBoard.hasQueen(otherRow, otherColumn) {
47+
return false
48+
}
49+
}
50+
for otherRow, otherColumn := row, column; onBoard(otherRow, otherColumn); otherRow, otherColumn = otherRow+1, otherColumn-1 {
51+
if thisBoard.hasQueen(otherRow, otherColumn) {
52+
return false
53+
}
54+
}
55+
for otherRow, otherColumn := row, column; onBoard(otherRow, otherColumn); otherRow, otherColumn = otherRow-1, otherColumn+1 {
56+
if thisBoard.hasQueen(otherRow, otherColumn) {
57+
return false
58+
}
59+
}
60+
61+
return true
62+
}
63+
64+
func arrange(boardState *chessBoard, alreadyDeployed int) int {
65+
boardSize := len(*boardState)
66+
if alreadyDeployed == boardSize {
67+
return 1
68+
}
69+
70+
arrangementCount := 0
71+
for column := 0; column < boardSize; column++ {
72+
if boardState.isSafe(alreadyDeployed, column) {
73+
boardState.putQueen(alreadyDeployed, column)
74+
arrangementCount += arrange(boardState, alreadyDeployed+1)
75+
boardState.removeQueen(alreadyDeployed, column)
76+
}
77+
}
78+
return arrangementCount
79+
}
80+
81+
func GetArrangementsCount(boardSize int) int {
82+
board := newChessBoard(boardSize)
83+
return arrange(board, 0)
84+
}

problem038/problem038_test.go

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package problem038
2+
3+
import (
4+
"fmt"
5+
"testing"
6+
)
7+
8+
func TestGetArrangementsCount(t *testing.T) {
9+
correctAnswers := []int{1, 1, 0, 0, 2, 10, 4, 40, 92, 352, 724, 2680, 14200, 73712}
10+
for i := range correctAnswers {
11+
answer := GetArrangementsCount(i)
12+
if answer != correctAnswers[i] {
13+
t.Log(fmt.Sprintf("%d: %d != %d", i, answer, correctAnswers[i]))
14+
t.FailNow()
15+
}
16+
}
17+
}

0 commit comments

Comments
 (0)