问题
def queens(n: Int): List[List[(Int, Int)]] = {
def placeQueens(k: Int): List[List[(Int, Int)]] =
if (k == 0)
List(List())
else
for {
queens <- placeQueens(k - 1)
column <- 1 to n
queen = (k, column)
if isSafe(queen, queens)
} yield queen :: queens
placeQueens(n)
}
I don't understand how this code works, even tough I debugged in Eclipse. Can you explain step by step this code? By the way, code works correctly. I also understand the n-queens algorithm but I don't understand the mechanism of this code.
回答1:
Let's break it down.
def queens(n: Int): List[List[(Int, Int)]] = {
def placeQueens(k: Int): List[List[(Int, Int)]] =
if (k == 0)
List(List())
else
for {
queens <- placeQueens(k - 1)
column <- 1 to n
queen = (k, column)
if isSafe(queen, queens)
} yield queen :: queens
placeQueens(n)
}
We define a function queens(n: Int)
which returns every possible placement of n queens on an n*n chessboard. The functions queens
itself is very simple; it just delegates to an inner function, called placeQueens
.
placeQueens
has a base case listed first: if we are operating on a 0*0 chessboard and placing 0 queens, there is exactly one (very trivial) way to do it. Now, the meat of this function is in the for-loop.
for {
queens <- placeQueens(k - 1)
column <- 1 to n
queen = (k, column)
if isSafe(queen, queens)
} yield queen :: queens
Parts of this can be read like a "traditional" for-loop, but some of it is not so straightforward. Scala's for-loop is based on Haskell's do-loop syntax, which probably explains some of your confusion. The way to read this is:
// We're starting a for-loop
for {
// Call placeQueens recursively. placeQueens returns a list of
// all possible results, so iterate over them.
queens <- placeQueens(k - 1)
// Iterate over each column that the kth queen could go in.
column <- 1 to n
// Assign the queen to that position.
queen = (k, column)
// If the position is safe, keep going. More precisely, if the position
// is NOT safe, stop.
if isSafe(queen, queens)
// Put our new queen assignment at the beginning of the recursively computed list.
} yield queen :: queens
These loops take some getting used to. It can be educational to desugar the loop (which is what the compiler does anyway) by hand to see what it means. You can find the translation rules on the Scala website.
来源:https://stackoverflow.com/questions/42789854/n-queens-in-scala