Scheme 解决方案中的八个皇后
我开始编写一个函数,以查看皇后是否从板上的其他位置“安全”,板的形式为Scheme 解决方案中的八个皇后,scheme,lisp,sicp,n-queens,Scheme,Lisp,Sicp,N Queens,我开始编写一个函数,以查看皇后是否从板上的其他位置“安全”,板的形式为(row col)和1-indexed。以下是我迄今为止所做的: (define (get-row p) (car p)) (define (get-col p) (cadr p)) (define (is-equal p1 p2) (and (= (car p1) (car p2)) (= (cadr p1) (cadr p2)))) (define (safe? k positions) (filter
(row col)
和1-indexed。以下是我迄今为止所做的:
(define (get-row p) (car p))
(define (get-col p) (cadr p))
(define (is-equal p1 p2)
(and (= (car p1) (car p2)) (= (cadr p1) (cadr p2))))
(define (safe? k positions)
(filter
(lambda (p) (not (and (is-equal p
(list (get-row p) k))
(is-equal p
(list (+ (get-row p) (- k (get-col p)))
k
))
(is-equal p
(list (- (get-row p) (- k (get-col p)))
k
)))))
positions))
我试着称之为:
(safe? 4 '((3 1) (1 2) (4 3) (2 4)))
查看棋盘上位置为(2 4)
的第四个皇后(第四列)是否安全
然而,我目前所拥有的是广泛的标记和返回基本上所有的'其他'列,而不是一个我想要的。有什么更好的方法可以解决这个问题?有很多方法可以解决这个问题。首先,我建议董事会采用更简单的表示法,我选择使用数字列表。列表中的索引从一开始,指示皇后列及其行中的值(坐标原点在左上角,新位置在列表末尾相邻);所有其他位置都假定为空。例如,以下委员会:
(. Q)
(Q .)
将由列表”(2 1)
表示。在我的表述中,safe?
过程看起来是这样的——请注意,对角线?
检查的实现有点棘手:
; a new queen is safe iff there are no other queens in the same
; row nor in any of the diagonals preceding its current position
; we don't need to check the column, this is the only queen on it
(define (safe? col board)
(let ((row (list-ref board (- col 1))))
(and (<= (number-occurrences row board) 1)
(diagonals? row board))))
; counts how many times an element appears on a list
(define (number-occurrences e lst)
(count (curry equal? e) lst))
; traverses the board looking for other queens
; located in one of the diagonals, going backwards
; starting from the location of the newest queen
(define (diagonals? row board)
(let loop ((lst (cdr (reverse board)))
(upper (sub1 row))
(lower (add1 row)))
(or (null? lst)
(and (not (= (car lst) upper))
(not (= (car lst) lower))
(loop (cdr lst) (sub1 upper) (add1 lower))))))
如果愿意,可以修改上述代码以使用不同的坐标原点,或者使用坐标对来表示皇后
(safe? 4 '(2 4 1 3))
=> #t