scheme解决八皇后问题
此前描述了一个枚举、过滤、重组的过程,通过这一过程也能解决嵌套循环的问题。
练习2.40 请定义过程unique-pairs,给它整数n,它能产生序对(i,j),其中1≤j≤i≤n
点击查看代码
(define nil '())
(define (enumerate-interval low high)
(if (> low high)
nil
(cons low (enumerate-interval (+ low 1) high))))
(define (unique-pairs n)
(map (lambda (i)
(map (lambda (j) (list i j))
(enumerate-interval 1 (- i 1))))
(enumerate-interval 1 n)))
点击查看代码
(define (flatmap proc seqs)
(accumulate append nil (map proc seqs)))
(define (accumulate op initial seq)
(if (null? seq)
initial
(op (car seq)
(accumulate op initial (cdr seq)))))
(define (filter proc seqs)
(cond ((null? seqs) nil)
((proc (car seqs)) (cons (car seqs) (filter proc (cdr seqs))))
(else (filter proc (cdr seqs)))))
(define (third-pairs n)
(flatmap
(lambda (i)
(flatmap
(lambda (j)
(map (lambda (k)
(list i j k))
(enumerate-interval 1 (- j 1))))
(enumerate-interval 1 (- i 1))))
(enumerate-interval 1 n)))
(define (ordered-triples-sum n s)
(filter (lambda (x) (= (accumulate + 0 x) s))
(third-pairs n)))
点击查看代码
;定义空棋盘
(define nil '())
(define empty-board nil)
;通过append进行累积
(define (flatmap proc seqs)
(accumulate append nil (map proc seqs)))
(define (accumulate op initial seqs)
(if (null? seqs)
initial
(op (car seqs)(accumulate op initial (cdr seqs)))))
;过滤
(define (filter predicate sequence)
(cond ((null? sequence) nil)
((predicate (car sequence))
(cons (car sequence)
(filter predicate (cdr sequence))))
(else (filter predicate (cdr sequence)))))
;通过生成一个整数序列,由于每一列都需要填入一个棋子,在解答皇后问题时,可以只录入每列的位置。在序对中可以表示为,(position,1-k)
(define (enumerate-interval low high)
(if ( > low high)
nil
(cons low (enumerate-interval (+ low 1) high))))
(define (queens board-size)
(define (queens-cols k)
(if (= k 0)
(list empty-board)
(filter
(lambda (positions) (safe? k positions))
(flatmap
(lambda (rest-of-queens)
(map
(lambda (new-row)
(adjoin-positions new-row k rest-of-queens))
(enumerate-interval 1 board-size)))
(queens-cols (- k 1))))))
(queens-cols board-size))
;录入新的棋子位置,录在前面比较容易提取
(define (adjoin-positions new-row k rest-of-queens)
(cons new-row rest-of-queens))
;判断一个棋子是否安全:是否和其他棋子在同一行?是否和其他棋子在同一对角线?只需要判断最新的棋子位置,但也要遍历所有已确定的棋子
(define (safe? k positions)
(define (same-row? v0 v1)
(= (car v0)(car v1)))
(define (same-diag? v0 v1)
(= (abs (- (car v0) (car v1)))
(abs (- (cdr v0) (cdr v1)))))
(let ((pair-list (map cons positions (enumerate-interval 1 k))))
(let ((val (car pair-list)))
(= (length
(filter
(lambda (x) (or (same-row? x val) (same-diag? x val)))
(cdr pair-list))) 0 ))))

浙公网安备 33010602011771号