2.42 Exercise 2.42
I consider this exercise unfinished
First, a utility procedure for finding if any element in a sequence evaluates
to true:
(define (any? s) | (cond ((null? s) #f) | ((car s) #t) | (else (any? (cdr s))))) |
|
We can use this in the safe? procedure, testing if the new piece conflicts
with any of the other ones. This uses a conflicts? procedure which tests if
two pieces lay in the same row or on a diagonal.
(define (safe? k positions) | (define (conflicts? positions i j) | (let ((ri (list-ref positions i)) | (rj (list-ref positions j))) | (or | (= ri rj) | (on-diagonal? i ri j rj)))) | (not | (any? | (map (lambda (i) (conflicts? positions i (- k 1))) | (enumerate-interval 0 (- k 2)))))) |
|
The procedure on-diagonal? has an awkward interface and is sort of
obscure. Assuming that the j is greater than i, it returns true if
either the element in column j is in the space j - i rows above the
element in row i (meaning the piece in column j is diagonally up and to
the right from that in i), or if the reverse is true and the piece in column
i is on an upper diagonal from that in column j.
(define (on-diagonal? i ri j rj) | | (let ((d (- j i))) | (or | | (= rj (+ ri d)) | | (= ri (+ rj d))))) |
|
Simply representing the current queen position as a list with one element per queen,
it is natural that empty-board is just an empty list and that adjoin-position
just appends the new position to the end of an existing list:
(define (adjoin-position new-row k rest-of-queens) | (append rest-of-queens (list new-row))) |
|
adjoin-position takes the new column k in the given queens procedure.