# 练习 2.42¶

;;; 42-empty-board.scm

(define empty-board '())


## 添加皇后¶

;;; 42-adjoin-position.scm

(cons new-row rest-of-queens))


## 过滤不安全的皇后¶

safe? 以及它的辅助函数 iter-check 完成过滤不安全皇后的操作，对于一个给定的新皇后行，它迭代地向棋盘的下方检查是否有已存在的皇后和新皇后的行发生冲突：

;;; 42-safe.scm

(define (safe? k position)
(iter-check (car position)
(cdr position)
1))

(define (iter-check row-of-new-queen rest-of-queens i)
(if (null? rest-of-queens)  ; 下方所有皇后检查完毕，新皇后安全
#t
(let ((row-of-current-queen (car rest-of-queens)))
(if (or (= row-of-new-queen row-of-current-queen)           ; 行碰撞
(= row-of-new-queen (+ i row-of-current-queen))     ; 右下方碰撞
(= row-of-new-queen (- row-of-current-queen i)))    ; 左下方碰撞
#f
(iter-check row-of-new-queen
(cdr rest-of-queens)    ; 继续检查剩余的皇后
(+ i 1))))))            ; 更新步进值


8                                           (safe? 4 (list 5 8 2 4))

7

6

5

4                   o

3                               o

2       o

1               o

1   2   3   4   5   6   7   8

8                                           (iter-check 4 (list 5 8 2 4) 1)

7

6

5

4                   o

3               x   x   x       o

2       o

1               o

1   2   3   4   5   6   7   8

8                                           (iter-check 5 (list 2 4) 2)

7

6

5

4                   o

3               x   x   x       o

2       o   x       x       x

1               o

1   2   3   4   5   6   7   8

8                                           (iter-check 5 (list 4) 3)

7

6

5

4                   o

3               x   x   x       o

2       o   x       x       x

1       x       o   x           x

1   2   3   4   5   6   7   8


## 生成八皇后的所有解¶

1 ]=> (load "42-queens.scm")

;  ... done
;... done
;Value: queens

1 ]=> (for-each (lambda (pos)
(begin
(display pos)
(newline)))
(queens 8))

(4 2 7 3 6 8 5 1)
(5 2 4 7 3 8 6 1)
(3 5 2 8 6 4 7 1)
(3 6 4 2 8 5 7 1)
(5 7 1 3 8 6 4 2)
(4 6 8 3 1 7 5 2)
(3 6 8 1 4 7 5 2)
(5 3 8 4 7 1 6 2)
(5 7 4 1 3 8 6 2)
(4 1 5 8 6 3 7 2)
(3 6 4 1 8 5 7 2)
(4 7 5 3 1 6 8 2)
(6 4 2 8 5 7 1 3)
(6 4 7 1 8 2 5 3)
(1 7 4 6 8 2 5 3)
(6 8 2 4 1 7 5 3)
(6 2 7 1 4 8 5 3)
(4 7 1 8 5 2 6 3)
(5 8 4 1 7 2 6 3)
(4 8 1 5 7 2 6 3)
(2 7 5 8 1 4 6 3)
(1 7 5 8 2 4 6 3)
(2 5 7 4 1 8 6 3)
(4 2 7 5 1 8 6 3)
(5 7 1 4 2 8 6 3)
(6 4 1 5 8 2 7 3)
(5 1 4 6 8 2 7 3)
(5 2 6 1 7 4 8 3)
(6 3 7 2 8 5 1 4)
(2 7 3 6 8 5 1 4)
(7 3 1 6 8 5 2 4)
(5 1 8 6 3 7 2 4)
(1 5 8 6 3 7 2 4)
(3 6 8 1 5 7 2 4)
(6 3 1 7 5 8 2 4)
(7 5 3 1 6 8 2 4)
(7 3 8 2 5 1 6 4)
(5 3 1 7 2 8 6 4)
(2 5 7 1 3 8 6 4)
(3 6 2 5 8 1 7 4)
(6 1 5 2 8 3 7 4)
(8 3 1 6 2 5 7 4)
(2 8 6 1 3 5 7 4)
(5 7 2 6 3 1 8 4)
(3 6 2 7 5 1 8 4)
(6 2 7 1 3 5 8 4)
(3 7 2 8 6 4 1 5)
(6 3 7 2 4 8 1 5)
(4 2 7 3 6 8 1 5)
(7 1 3 8 6 4 2 5)
(1 6 8 3 7 4 2 5)
(3 8 4 7 1 6 2 5)
(6 3 7 4 1 8 2 5)
(7 4 2 8 6 1 3 5)
(4 6 8 2 7 1 3 5)
(2 6 1 7 4 8 3 5)
(2 4 6 8 3 1 7 5)
(3 6 8 2 4 1 7 5)
(6 3 1 8 4 2 7 5)
(8 4 1 3 6 2 7 5)
(4 8 1 3 6 2 7 5)
(2 6 8 3 1 4 7 5)
(7 2 6 3 1 4 8 5)
(3 6 2 7 1 4 8 5)
(4 7 3 8 2 5 1 6)
(4 8 5 3 1 7 2 6)
(3 5 8 4 1 7 2 6)
(4 2 8 5 7 1 3 6)
(5 7 2 4 8 1 3 6)
(7 4 2 5 8 1 3 6)
(8 2 4 1 7 5 3 6)
(7 2 4 1 8 5 3 6)
(5 1 8 4 2 7 3 6)
(4 1 5 8 2 7 3 6)
(5 2 8 1 4 7 3 6)
(3 7 2 8 5 1 4 6)
(3 1 7 5 8 2 4 6)
(8 2 5 3 1 7 4 6)
(3 5 2 8 1 7 4 6)
(3 5 7 1 4 2 8 6)
(5 2 4 6 8 3 1 7)
(6 3 5 8 1 4 2 7)
(5 8 4 1 3 6 2 7)
(4 2 5 8 6 1 3 7)
(4 6 1 5 2 8 3 7)
(6 3 1 8 5 2 4 7)
(5 3 1 6 8 2 4 7)
(4 2 8 6 1 3 5 7)
(6 3 5 7 1 4 2 8)
(6 4 7 1 3 5 2 8)
(4 7 5 2 6 1 3 8)
(5 7 2 6 3 1 4 8)
;Unspecified return value