;;; ------------------------------------------------------------------
;;; --- Input list has #t and '() atoms only. Output #t if one is #t.
;;;
(define yes
(lambda (list)
(letrec ((alpha
(lambda (l)
(if (null? l)
#f
(if (eq? (car l) #t)
#t
(alpha (cdr l)))))))
(alpha list))))
;;; ------------------------------------------------------------------
;;; --- Value is #T iff it is OK to put a queen in new-col row of the new column.
;;;
(define next-col
(lambda (new-col old-col-list)
(let ((poa (letrec
((alpha
(lambda (p l)
(if (null? p)
l
(alpha (cdr p) (cons (+ 1 (car l)) l))))))
(alpha old-col-list '(0)))))
(not (yes (map (lambda (x pos)
(or
(= new-col x)
(= (+ pos new-col) x)
(= (- new-col pos) x)))
old-col-list poa))))))
;;; -------------------------------------------------------------------------
;;; --- Argument n is number of columns remaining, m is number columns total,
;;; --- l is the current list of rows in which queens are located.
;;;
(define queen
(lambda (n m l)
(if (= n 0)
(list l)
(letrec
((q (lambda (x acc)
(if (> x m)
acc
(if (next-col x l)
(q (+ x 1) (append acc (queen (- n 1) m (append l (list x)))))
(q (+ x 1) acc))))))
(q 1 '())))))
;;; -------------------------------------------------------------------
;;; --- Main function - Usage: (n-queen 8)
;;;
(define n-queen
(lambda (n)
(queen n n '())))