exercise-42.scm (3695B)
1 (define-library (sicp solutions chapter-2 exercise-42) 2 (import (scheme base) 3 (srfi :1) 4 (only (sicp utils) flatmap)) 5 (export safe? queens make-position) 6 7 (begin 8 (define (make-position row column) 9 (cons row column)) 10 11 (define (position-row position) 12 (car position)) 13 14 (define (position-column position) 15 (cdr position)) 16 17 (define (adjoin-position row column rest-of-queens) 18 (cons (make-position row column) 19 rest-of-queens)) 20 21 (define empty-board '()) ;; queens 0 will return [[]]. 22 23 (define (threatening-pair? queen-a-position queen-b-position) 24 (define a-row (position-row queen-a-position)) 25 (define b-row (position-row queen-b-position)) 26 27 (define a-column (position-column queen-a-position)) 28 (define b-column (position-column queen-b-position)) 29 30 (define rows-equal (= a-row 31 b-row)) 32 33 (define on-same-diagonal (= (abs (- a-row 34 b-row)) 35 (abs (- a-column 36 b-column)))) 37 38 (or rows-equal 39 on-same-diagonal)) 40 41 " 42 Q 43 Q 44 Q 45 46 Q1 = (2, 1) 47 Q2 = (3, 2) 48 Q1 - Q2 = (2 - 3, 1 - 2) 49 = (-1, -1) 50 Q3 = (4, 3) 51 Q1 - Q3 = (2 - 4, 1 - 3) 52 = (-2, -2) 53 54 Q 55 Q 56 Q 57 Q 58 59 Q1 = (4, 1) 60 Q2 = (3, 2) 61 Q3 = (2, 3) 62 63 Q1 - Q2 = (4 - 3, 1 - 2) 64 = (1, -1) 65 Q1 - Q3 = (4 - 2, 1 - 3) 66 = (2, -2) 67 Q1 - Q4 = (4 - 1, 1 - 4) 68 = (3, -3) 69 " 70 71 72 (define (safe? our-column board) 73 (define our-row (position-row (car board))) 74 75 (if (null? 76 (filter 77 (lambda (position) 78 (threatening-pair? 79 (make-position our-row 80 our-column) 81 position)) 82 (cdr board))) 83 #t 84 #f)) 85 86 (define (queens board-size) 87 (define (queen-cols k) 88 (if (= k 0) 89 (list empty-board) 90 (filter 91 (lambda (positions) 92 (safe? k 93 positions)) 94 (flatmap 95 (lambda (rest-of-queens) 96 (map (lambda (new-row) 97 (adjoin-position 98 new-row 99 k 100 rest-of-queens)) 101 (enumerate-interval 102 1 103 board-size))) 104 (queen-cols (- k 1)))))) 105 (queen-cols board-size)) 106 107 (define (display-board board n) 108 (define sorted-board 109 (sort board 110 (lambda (a b) 111 (or 112 (< (position-row a) 113 (position-row b)) 114 ;; (< (position-column a) 115 ;; (position-column b)) 116 )))) 117 '(define sorted-board board) 118 119 (define (display-row column n) 120 (pretty-print (list column n)) 121 (cond 122 ((zero? n) '()) 123 ((= column n) 124 (display "Q\n") 125 (display-row column (- n 1))) 126 (else (display ".") 127 (display-row column (- n 1))))) 128 129 (for-each 130 (lambda (position) 131 (display-row 132 (position-column position) 133 n)) 134 sorted-board)) 135 136 '(for-each (lambda (board) 137 (display-board board 138 (reduce 139 (lambda (x y) 140 (max (position-column x) 141 (position-column y))) 142 0 143 board)) 144 (pretty-print board)) 145 (flatmap queens 146 (enumerate-interval 1 8)))))