Eight Queens puzzle (Haskell)
From LiteratePrograms
The n-Queens is the extension of the 8-Queens problem to an n by n chessboard. The challenge is to place n queens on an n by n chessboard such that no two queens are attacking each other.
We represent solutions by a list of integers, [Int]
. The list [r1,...,rn]
represents n
queens in the positions:
[(1,r1),...,(n,rn)]
.
A safe set of queens
We start by defining a function safeAddition
that determines whether adding a queen at (0,r0)
is safe. We do this by checking the list [r1,...,rn]
to determine if:
- ri = r0 or
-
abs (r0 - ri) = i
for any i
in [1..n]
.
The first condition determines whether two queens are in the same row. The corresponding condition for columns is satisfied as a result of our data-structure: a list of n
queens represents n
queens in adjacent columns. The second condition determines whether queen 0
is attacking queen i
on the diagonal: whether their horizontal separation, i - 0
, is equal to their vertical separation, ri - r0
. If either of these conditions is true the addition is not safe.
<<safeAddition>>= safeAddition :: [Int] -> Int -> Int -> Bool safeAddition [] _ _ = True safeAddition (r:rows) row i = row /= r && abs (row - r) /= i && safeAddition rows row (i + 1)
This function is therefore called as safeAddition currentRows newRow 1
to determine whether the addition is safe.
Finding solutions
We find solutions by placing queens on the board, one at a time, from right to left. In the following code, we perform a fold over the number of queens from 1 to n
. At each step, the function f
returns all solutions that can be safely created by adding a queen in row
to a previous solution for k - 1
queens. This is performed using a simple list comprehension:
<<queens>>= queens :: Int -> [[Int]] queens n = foldM f [] [1..n] where f rows _ = [row : rows | row <- [1..n], safeAddition rows row 1]
Running
The code then performs as follows:
*Main> queens 8 [[4,2,7,3,6,8,5,1],[5,2,4,7,3,8,6,1], [3,5,2,8,6,4,7,1],[3,6,4,2,8,5,7,1], [5,7,1,3,8,6,4,2],...]
Download code |