[UMN logo]

CSCI 5106: Programming Languages
Spring 2006, University of Minnesota

SML Program for Finding All Solutions to the N-Queens Problem


(* 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