Try using a seq{} expressions - you should be able to yield each solution you find:

[link:msdn.microsoft.com]

By on 6/10/2010 7:44 PM ()

This is a (rather inefficient) implementation using lazy sequences. It works by generating n branches, each corresponding to placing a queen in each column on the first row, and by trying to extend each partial solution with a queen on the next row.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
let testAttack partialPlace r c =
    if Seq.exists (fun (pr, pc) -> pr = r || pc = c || pr + pc = r + c || pr - pc = r - c) partialPlace
    then Seq.empty else Seq.append partialPlace (Seq.singleton (r, c))


let generateRow r n partialPlaces =
    partialPlaces |> Seq.collect (fun partial -> { 1..n } (* Cols *) |> Seq.map (testAttack partial r) |> Seq.filter (Seq.isEmpty >> not))


let queens n =
    { 2..n } (* Rows *) |> Seq.fold (fun partialPlaces row -> generateRow row n partialPlaces) (Seq.init n (fun c -> Seq.singleton (1, c + 1)))


(queens 4);;
(queens 8);;
By on 6/16/2010 9:49 AM ()

A variation with sequence expressions:

1
2
3
4
5
6
7
8
9
let queensSE n = seq {
    let rec solve partials = seq {
        for partial in partials do
            let lastRow = Seq.length partial
            if lastRow = n then yield partial
            else yield! solve ( { 1..n } (* Cols *) |> Seq.map (testAttack partial (lastRow + 1)) |> Seq.filter (Seq.isEmpty >> not) )
    }
    yield! solve (Seq.init n (fun c -> Seq.singleton (1, c + 1)))
}
By on 6/16/2010 10:38 AM ()
IntelliFactory Offices Copyright (c) 2011-2012 IntelliFactory. All rights reserved.
Home | Products | Consulting | Trainings | Blogs | Jobs | Contact Us | Terms of Use | Privacy Policy | Cookie Policy
Built with WebSharper