sicp-2.2.3

Posted on 2015-02-18 19:31:27 +0900 in SICP Lisp

2.33

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

(accumulate + 0 (list 1 2 3 4 5))

(define (map p sequence)
   (accumulate (lambda (x y) (cons (p x) y)) null sequence))

(define (square x) (* x x))

(map square '(1 2 3))

(define (append seq1 seq2)
   (accumulate cons seq2 seq1))

(append (list 1 2 3) (list 4 5 6))

(define (length sequence)
   (accumulate (lambda (x y) (+ 1 y)) 0 sequence))

(length '(1 2 3))

The append is kind of tricky to me at first glance. Just remaind me this equition: cons 1 (list 2 3) = (list 1 2 3)

2.34

(define (horner-eval x coefficient-sequence)
   (accumulate (lambda (this-coeff higher-terms)
                 (+ this-coeff
                    (* x higher-terms)))
               0
               coefficient-sequence))

(horner-eval 2 (list 1 3 0 5 0 1))

2.35

(define (count-leaves t)
   (accumulate + 0 (map
                     (lambda (x)
                       (if (not (pair? x))
                         1
                         (count-leaves x)))
                     t)))

This is the most elegant way, which flats the tree structure recursively.

2.36

(define (accumulate-n op init seqs)
   (if (null? (car seqs))
       null
       (cons (accumulate op init
                         (map (lambda (x)
                                (car x))
                              seqs))
             (accumulate-n op init
                           (map (lambda (x)
                                  (cdr x))
                                seqs)))))

(accumulate-n + 0 '((1 2 3) (4 5 6) (7 8 9) (10 11 12)))

2.37

(define (dot-product v w)
   (accumulate + 0 (map * v w)))

(define (matrix-*-vector m v)
   (map (lambda (row)
          (dot-product v row)) m))

(define m0 '((1 2 3 4) (4 5 6 6) (6 7 8 9)))
(matrix-*-vector m0 '( 2 1 4 5))

(define (transpose mat)
   (accumulate-n cons null  mat))

(transpose m0)

(define (matrix-*-matrix m n)
   (let ([cols (transpose n)])
      (map (lambda(v) (matrix-*-vector cols v)) m)))

(matrix-*-matrix m0 (transpose m0))

2.38

(define (fold-right op initial sequence)
   (if (null? sequence)
       initial
       (op (car sequence)
           (fold-right op initial (cdr sequence)))))

(define (fold-left op initial sequence)
   (define (iter result rest)
     (if (null? rest)
         result
         (iter (op result (car rest))
               (cdr rest))))
   (iter initial sequence))

(fold-right / 1 (list 1 2 3))
3/2
(fold-left / 1 (list 1 2 3))
1/6
(fold-right list null (list 1 2 3))
(1 (2 (3 ())))
(fold-left list null (list 1 2 3))
(((() 1) 2) 3)

Both associativity and commutativity. That is

(op a b) = (op b a) and (op (op a b) c) = (op a (op b c))

2.39

(define (reverse sequence)
  (fold-right (lambda (x y)
                (append y (list x)))
              null
              sequence))

(reverse (list 1 2 3 4))

(define (reverse sequence)
  (fold-left (lambda (x y)
                (cons y  x))
              null
              sequence))

(reverse (list 1 2 3 4))

2.40

(define (unique-pairs n)
  (flatmap (lambda (i)
             (map (lambda (j) (list i j))
                  (enumerate-interval 1 (- i 1))))
           (enumerate-interval 1 n)))

(define (prime-sum-pairs n)
   (map make-pair-sum
        (filter prime-sum?
                (unique-pairs n))))

2.41

(define (unique-triples 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 (equal-sum? s)
  (lambda (lst)
    (= s (accumulate + 0 lst))))

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 (adjoin-position row k rest-of-queens)
  (append rest-of-queens (list (list row k))))

(define (last l)
    (cond ((null? (cdr l)) (car l))
          (else (last (cdr l)))))

(define (safe? k positions)
  (define (attack? q1 q2)
    (and (not (= (car q1) (car q2)))
         (not (= (abs (- (car q1) (car q2)))
                 (abs (-  (cadr q1)(cadr q2)))))))

  (let ((new-queen (last positions)))
    (define (check i positions)
      (cond ((= i k) true)
            ((attack? (car positions) new-queen)
             (check (+ i 1) (cdr positions)))
            (else false)))
    (check 1 positions)))

summary

The key idea to understand map, flatmap is to relate it with Category Theory. To think about something more abstractly would help a lot in understanding concrete concepts. Knowing HOW is the key to finish something, but WHY is the key to master something.

----------------------------------- 本文内容遵从CC版权协议转载请注明出自kamelzcs -----------------------------------
«  | sicp-2-2-2 »

Hide Comments

comments powered by Disqus