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.