#! /bin/sh
exec ../src/sizzle -qs $0 $*
!#
;; test/queens.scm -- tests for the Posix/Unix functions
;;
;; The algorithm presented here is taken from the book `Scheme and the
;; Art of Programming' by George Springer and Daniel P. Friedman

;; Load the test framework.

(load "test-suite.scm")

(begin-section "eight queens")

(define (legal? try legal-pl)
  (letrec ((good?
	    (lambda (new-pl up down)
	      (cond
	       ((null? new-pl) #t)
	       (else (let ((next-pos (car new-pl)))
		       (and
			(not (= next-pos try))
			(not (= next-pos up))
			(not (= next-pos down))
			(good? (cdr new-pl)
			       (+ up 1)
			       (- down 1)))))))))
    (good? legal-pl (+ try 1) (- try 1))))

(define (solution? legal-pl)
  (= (length legal-pl) 8))

(define fresh-try 8)

(define (build-solution legal-pl)
  (cond
   ((solution? legal-pl) legal-pl)
   (else (forward fresh-try legal-pl))))

(define (forward try legal-pl)
  (cond
   ((zero? try) (backtrack legal-pl))
   ((legal? try legal-pl) (build-solution (cons try legal-pl)))
   (else (forward (- try 1) legal-pl))))

(define (backtrack legal-pl)
  (cond
   ((null? legal-pl) '())
   (else (forward (- (car legal-pl) 1) (cdr legal-pl)))))
			     
(define (build-all-solutions)
  (letrec ((loop (lambda (sol)
		   (cond
		    ((null? sol) '())
		    (else (cons sol (loop (backtrack sol))))))))
    (loop (build-solution '()))))

(pass-if (build-solution '()) '(5 7 2 6 3 1 4 8) equal?)
(pass-if (length (build-all-solutions)) 92 =)
(test-summary)
