This is what I came up with for the second time. Not sure if this is much faster. A little more beautiful.
(define (n-queens n) (let loop ((k 1) (r 1) (dangers (starting-dangers n)) (res '()) (solutions '())) (cond ((> kn) (cons res solutions)) ((> rn) solutions) ((safe? rk dangers) (let ((this (loop (+ k 1) 1 (update-dangers rk dangers) (cons (cons rk) res) solutions))) (loop k (+ r 1) dangers res this))) (else (loop k (+ r 1) dangers res solutions)))))
The big thing is to use the let statement to serialize the recursion, limiting the depth to n. The solutions go back (maybe you can fix it by going n-> 1 instead of 1-> n to r and k), but the back set is the same set as the set frowards.
(define (starting-dangers n) (list (list) (list (- n)) (list (+ (* 2 n) 1)))) ;;instead of terminating in null list, terminate in term that cant threaten
a slight improvement, the danger can come from a row, diagonal or diagonal up, follow each as the board develops.
(define (safe? rk dangers) (and (let loop ((rdangers (rdang dangers))) (cond ((null? rdangers) #t) ((= r (car rdangers)) #f) (else (loop (cdr rdangers))))) (let ((ddiag (- kr))) (let loop ((ddangers (ddang dangers))) (if (<= (car ddangers) ddiag) (if (= (car ddangers) ddiag) #f #t) (loop (cdr ddangers))))) (let ((udiag (+ kr))) (let loop ((udangers (udang dangers))) (if (>= (car udangers) udiag) (if (= (car udangers) udiag) #f #t) (loop (cdr udangers)))))))
average improvement in format change, you only need to make one comparison to check against the previous two. Donβt think that ordered diagonals sorted me, it cost me nothing, but I donβt think it saves time either.
(define (update-dangers rk dangers) (list (cons r (rdang dangers)) (insert (- kr) (ddang dangers) >) (insert (+ kr) (udang dangers) <))) (define (insert x sL pred) (let loop ((L sL)) (cond ((null? L) (list x)) ((pred x (car L)) (cons x L)) (else (cons (car L) (loop (cdr L))))))) (define (rdang dangers) (car dangers)) (define (ddang dangers) (cadr dangers)) (define (udang dangers) (caddr dangers))
source share