Skip to content

Instantly share code, notes, and snippets.

@sergey-tihon
Created July 14, 2013 20:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sergey-tihon/5995802 to your computer and use it in GitHub Desktop.
Save sergey-tihon/5995802 to your computer and use it in GitHub Desktop.
The N Queens problem!
type ChessboardState =
{Row:bool[]; DiagPlus:bool[]; DiagMin:bool[]}
let inline diagMinInd (chessboard:ChessboardState) (x,y) =
if x-y>=0 then x-y else x-y+chessboard.DiagMin.Length
let canPlaceOn (chessboard:ChessboardState) (x,y) =
chessboard.Row.[y] && chessboard.DiagPlus.[x+y] && chessboard.DiagMin.[diagMinInd chessboard (x,y)]
let changeState (chessboard:ChessboardState) (x,y) =
chessboard.Row.[y] <- not chessboard.Row.[y]
chessboard.DiagPlus.[x+y] <- not chessboard.DiagPlus.[x+y]
chessboard.DiagMin.[diagMinInd chessboard (x,y)] <- not chessboard.DiagMin.[diagMinInd chessboard (x,y)]
let nqueens n =
let rec solve x (chessboard:ChessboardState) =
if x > n then 1
else
[1..n]
|> List.filter (fun y-> (x,y) |> canPlaceOn chessboard)
|> List.sumBy (fun y->
(x,y) |> changeState chessboard
let res =solve (x+1) chessboard
(x,y) |> changeState chessboard
res)
// Count solutions where fst queen is (1,y)
let pSolve y =
let chessboard = {Row = Array.create (n+1) true;
DiagPlus = Array.create (2*n+1) true;
DiagMin = Array.create (2*n+1) true}
(1,y) |> changeState chessboard
let mul = if (2*y<=n) then 2 else 1 // Solution symmetricity
mul*(solve 2 chessboard)
let result =
[|1..(n+1)/2|]
|> Array.Parallel.map pSolve
|> Array.sum
printfn "No. of solutions: %A for n=%A" (result) n
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment