(* Finding all solutions to n queens *)
exception Placement_Impossible
exception Nqueens
fun m_to_n m n = if m = n then [m]
else m :: (m_to_n (m + 1) n)
fun upto_n n = m_to_n 1 n
fun append [] l = l
| append (hd :: tl) l = hd :: (append tl l)
fun attack_aux (Pos:int) (Dif:int) ([]:(int list)) = false
| attack_aux Pos Dif (FstPlaced :: Rest) =
if Pos > FstPlaced
then ((Pos - Dif = FstPlaced) orelse attack_aux Pos (Dif + 1) Rest)
else ((Pos + Dif = FstPlaced) orelse attack_aux Pos (Dif + 1) Rest)
fun attack Pos Placed = attack_aux Pos 1 Placed
fun place_queens Cols CurBrd =
(if Cols = nil
then present_solution CurBrd
else place_queens_aux [] Cols CurBrd)
and
place_queens_aux UsedPos nil Placed =
raise Placement_Impossible
| place_queens_aux UsedPos (Pos :: Rest) Placed =
if attack Pos Placed
then place_queens_aux (Pos :: UsedPos) Rest Placed
else (place_queens (append UsedPos Rest) (Pos :: Placed)
handle Placement_Impossible => (place_queens_aux (Pos :: UsedPos)
Rest Placed))
and present_solution CurBrd =
let fun present_sol_aux [] = (print "]")
| present_sol_aux (X::L) =
((print ",") ; (print (Int.toString X)) ; present_sol_aux L)
in (print "[") ;
(if (CurBrd = [])
then (print "]\n")
else ((print (Int.toString (hd CurBrd)));
(present_sol_aux (tl CurBrd)))) ;
if (TextIO.inputLine TextIO.stdIn) = SOME(";\n")
then ((print "\n") ;
raise Placement_Impossible)
else ()
end
fun nqueens n = (if n < 1 then raise Nqueens
else (place_queens (upto_n n) []))
handle Placement_Impossible => (print "no\n")
Last updated on April 27, 2006 by gopalan@cs.umn.edu