;;;Programmed
by Ron Danielson, 1/31/00
;;;
;;;This
set of functions finds one solution for the N queens problem.
;;;Rows
are tested sequentially, with a recursive function to trial
;;;place
a queen in various columns on that row.
(DEFINE
(SAFE board row col)
;;There is no diagonal attack if none of the
queens already on the board
;;are in the same column, or have a slope of
1 or -1 from the tested
;;position (checked by subtracting
corresponding row and column
;;coordinates, comparing absolute values of
result).
(DO ((test board (CDR test))
(result #t)
)
((null? test) result)
(COND
((OR (EQUAL? (ABS (- row (CAAR test)))
(ABS (- col (CADAR test)))
)
(EQUAL? col (CADAR test))
)
(SET! result #f))
)
)
)
(DEFINE
(PRINTSOLN board)
;;Recursively traverse board, printing out
each queen as it's encountered.
(COND ((NULL? board) #t)
(ELSE (DISPLAY (CAAR board))
(DISPLAY ", ")
(DISPLAY (CADAR board))
(DISPLAY "; ")
(PRINTSOLN (CDR board))
)
)
)
(DEFINE
(TRYROW currow n board)
(DO ((col 1 (+ col 1)) ;for col := 1 to n
(soln #f) ;set
T when solution found
)
((OR (> col n) soln) soln) ;stop loop if > n or solution found
(COND ((safe board currow col) ;check current position
(SET! board (CONS (LIST currow col) board)) ;add if OK
(COND ((< currow n) (SET!
soln (tryrow (+ currow 1) n board)))
;;if row < n,
try next row
(ELSE (SET! soln (printsoln board))) ;solution found
)
(SET! board (CDR board))
;backtrack - remove previous queen
)
)
)
)
(DEFINE
(QUEENS n)
(tryrow 1 n ())
)