Completed up to 2.42

This commit is contained in:
Oliver Payne 2021-11-11 22:29:11 +00:00
parent 28864609ed
commit 7d513dccf6
1 changed files with 65 additions and 0 deletions

View File

@ -87,3 +87,68 @@
(define (triple-leq-n-sum-s n s)
(filter (lambda (x) (= (sum x) s)) (ordered-triples n)))
;; EXERCISE 2.42
(define (queens board-size)
(define (queen-cols k)
(if (= k 0)
(list empty-board)
(filter
(lambda (positions) (safe? k positions))
(flatmap
(lambda (rest-of-queens)
(map (lambda (new-row)
(adjoin-position new-row k rest-of-queens))
(enumerate-interval 1 board-size)))
(queen-cols (- k 1))))))
(queen-cols board-size))
(define empty-board '())
(define (position row col) (cons row col))
(define (row position) (car position))
(define (col position) (cdr position))
(define (intercepts horiz pos neg) (list horiz pos neg))
(define (horiz intercepts) (car intercepts))
(define (pos intercepts) (cadr intercepts))
(define (neg intercepts) (caddr intercepts))
(define (col-k-pos k positions)
(car (filter (lambda (x) (= (col x) k)) positions)))
; Compute the y-intercepts of the horizontal line the line
; of gradient +1 and the line of gradient -1 through the
; given position. Any two positions that share one of these
; intercepts put are not safe wrt each other.
(define (compute-intercepts position)
(intercepts (row position)
(- (row position) (col position))
(+ (row position) (col position))))
(define (checks pos1 pos2)
(if (= (col pos1) (col pos2))
#f
(let ((int1 (compute-intercepts pos1))
(int2 (compute-intercepts pos2)))
(or (= (horiz int1) (horiz int2))
(= (pos int1) (pos int2))
(= (neg int1) (neg int2))))))
(define (adjoin-position row col rest-of-queens)
(append rest-of-queens (list (position row col))))
; Calculuate the intercepts of each of the position. If any
; match, then the k-th position is not safe.
(define (safe? k positions)
(if (= (col (car positions)) k) #t ; Need to only check with first k-1
(let* ((k-pos (col-k-pos k positions))
(k-int (compute-intercepts k-pos))
(int (compute-intercepts (car positions))))
(and (not (= (horiz int) (horiz k-int)))
(not (= (pos int) (pos k-int)))
(not (= (neg int) (neg k-int)))
(safe? k (cdr positions))))))
; Neater solution using map / accumulate with checks?
;(define (safe? k positions)
; (accumulate and #t (map