sicp-4-3-2

Posted on 2015-03-15 06:36:17 +0900 in SICP Lisp

4.39

    (require (> miller cooper))
    (require (not (= baker 5)))
    (require (not (= cooper 1)))
    (require (not (= fletcher 5)))
    (require (not (= fletcher 1)))
    (require (not (= (abs (- smith fletcher)) 1)))
    (require
     (distinct? (list baker cooper fletcher miller smith)))(require (not (= (abs (- fletcher cooper)) 1)))

The answer will always be correct, but the efficiency would be different.

By putting the more restrictive in the front makes the branch cutting happens earlier.

4.40

(define (multiple-dwelling)
 (let ((cooper (amb 2 3 4 5))
       (miller (amb 3 4 5)))
   (require (> miller cooper))
   (let ((fletcher (amb 2 3 4)))
     (require (not (= (abs (- fletcher cooper)) 1)))
     (let ((smith (amb 1 2 3 4 5)))
       (require (not (= (abs (- smith fletcher)) 1)))
       (let ((baker (amb 1 2 3 4)))
         (require
           (distinct? (list baker cooper fletcher miller smith)))
         (list (list 'baker baker)
               (list 'cooper cooper)
               (list 'fletcher fletcher)
               (list 'miller miller)
               (list 'smith smith)))))))

4.41

(define (accumulate op initial sequence)
  (if (null? sequence)
      initial
      (op (car sequence)
          (accumulate op initial (cdr sequence)))))

(define (flatmap proc seq)
  (accumulate append nil (map proc seq)))

(define (filter predicate sequence)
  (cond ((null? sequence) '())
        ((predicate (car sequence))
         (cons (car sequence)
               (filter predicate (cdr sequence))))
        (else (filter predicate (cdr sequence)))))

(define (permutations lst)
  (if (null? lst)
    (list '())
    (flatmap
      (lambda (first)
        (map
          (lambda (rest) (cons first rest))
          (permutations (filter (lambda (x) (not (= x first))) lst))))
      lst)))

(permutations '(1 2 3 4 5))

permutations function is the key point.

4.42

(define (xor a b)
  (or (and a (not b))
      (and (not a)b)))

(define liars
  (let ((betty (amb 1 2 3 4 5))
        (ethel (amb 1 2 3 4 5))
        (joan (amb 1 2 3 4 5))
        (kitty (amb 1 2 3 4 5))
        (mary (amb 1 2 3 4 5)))
    (require
      (distinct? (list betty ethel joan kitty mary)))
    (require (xor (= kitty 2) (= betty 3)))
    (require (xor (= ethel 1) (= joan 2)))
    (require (xor (= joan 3) (= ethel 5)))
    (require (xor (= kitty 2) (= mary 4)))
    (require (xor (= mary 4) (= betty 1)))
    (list (list 'betty betty)
          (list 'ethel ethel)
          (list 'joan joan)
          (list 'kitty kitty)
          (list 'mary mary))))

One important thing to note is, and and or is not a regular primitive function in Scheme, classification is here, it must be dealt with separatly.

4.44

(define (safe? result)
  (let ((p (car result)))
    (define (conflict? q i)
      (or
        (= p q)
        (= p (+ q i))
        (= p (- q i))))
    (define (check rest i)
      (cond
        ((null? rest) true)
        ((conflict? (car rest) i) false)
        (else (check (cdr rest) (+ i 1)))))
    (check (cdr result) 1)))

(define (queens n)
  (define (iter result left)
    (if (= 0 left)
      result
      (begin
        (let ((new (cons (an-integer-between 1 n)
                         result)))
          (require (safe? new))
          (iter new (- left 1))))))
  (iter '() n))

(queens 8)
----------------------------------- 本文内容遵从CC版权协议转载请注明出自kamelzcs -----------------------------------
«  | sicp-4-3-1 »

Hide Comments

comments powered by Disqus