sicp 2.2 习题

in drscheme '()=nil
2.17
(define (last-pair l)
  (if(equal? (cdr l) '())
     (car l)
     (last-pair (cdr l))))
2.18
(define (reverse l)
  (define (reverse-iter l r)
    (if(null? l)
       r
       (reverse-iter (cdr l) (append (list(car l)) r))))
  (reverse-iter l (list)))
a better version:
(define (reverse l)
  (if (null? l)
      '()
      (append (reverse (cdr l))(list(car l)))))
2.19
(define us-coins (list 50 25 10 5 1 ))
(define uk-coins (list 100 50 20 10 5 2 1 0.5))
(define (cc amount coin-values)
  (cond ((= amount 0) 1)
        ((or (< amount 0) (no-more? coin-values))0)
        (else
         (+ (cc amount
                (except-first-denomination coin-values))
            (cc (- amount
                   (first-denomination coin-values))
                coin-values)))))
(define (no-more? coin-values)
  (null? coin-values))
(define (first-denomination coin-values)
  (car coin-values))
(define (except-first-denomination coin-values)
  (cdr coin-values))
list中元素的顺序不影响结果,为什么呢?
现在可以发现函数抽象的好处了,当我们需要修改的时候只要修改相应的函数即可,无需修改框架。
2.20
(define (same-parity a . w)
  (define (f a w)
    (cond ((null? w) a)
          ((even? (- (car a) (car w))) (f (append a (list (car w))) (cdr w)))
          (else (f (append a '()) (cdr w)))))
  (f (list a) w))
2.21
(define (square-list item)
  (if(null? item)
     '()
     (cons (* (car item)(car item)) (square-list (cdr item)))))
(define (square-list item)
  (map (lambda (x) (* x x)) item))
2.22
这样写肯定会倒序排列的
这样写就好了
(define (square-list item)
  (define (iter things answer)
    (if (null? things)
        answer
        (iter (cdr things)
              (append answer
                    (list(square (car things)))))))
  (iter item '()))
2.23
(define (for-each f l)
  (cond ((null? l) (newline))
        (else (f (car l)) (for-each f (cdr l)))))
2.24
> (list 1 (list 2 (list 3 4)))
(1 (2 (3 4)))
    //
   1 //
    2 //
     3  4
2.25
(car (cdaddr (list 1 3 (list 5 7) 9)))
(caar (list (list 7)))
(cadr(cadr(cadr(cadr(cadr(cadr (list 1 (list 2 (list 3 (list 4 (list 5 (list 6 7))))))))))))
2.26
> (append x y)
(1 2 3 4 5 6)
> (cons x y)
((1 2 3) 4 5 6)
> (list x y)
((1 2 3) (4 5 6))
2.27
(define (deep-reverse item)
  (cond ((null? item) '())
        ((not(pair? item)) item)
        (else (append (deep-reverse(cdr item))
                      (list(deep-reverse (car item)))))))
2.28
(define (fringe tree)
  (cond ((null? tree) '())
        ((not(pair? tree)) (list tree))
        (else (append (fringe(car tree))(fringe(cdr tree))))))
2.29
a
(define (left-branch mobile)
  (car mobile))
(define (right-branch mobile)
  (cadr mobile))
(define (branch-length branch)
  (car branch))
(define (branch-structure branch)
  (cadr branch))
b
(define (total-weight mobile)
  (+ (left-branch mobile)
     (right-branch mobile)))
(define (weight branch)
  (if(not(pair? (branch-structure branch)))
     (branch-structure branch)
     (total-weight (branch-structure branch))))
c
(define (balanced? mobile)
  (let ((left (left-branch mobile))
        (right (right-branch mobile)))
    (if(and(and(mobile? (branch-structure left))
               (balanced? left))
           (and(mobile? (branch-structure right))
               (balanced? right))
           (=(*(branch-length left)(weight left))
             (*(branch-length right)(weight right))))
       #t
       #f)))
(define (mobile? branch)
  (if(pair? branch)
     #t
     #f))
d
(define (left-branch mobile)
  (car mobile))
(define (right-branch mobile)
  (cdr mobile))
(define (branch-length branch)
  (car branch))
(define (branch-structure branch)
  (cdr branch))
2.30
using map:
(define (square-tree tree)
  (map (lambda (sub-tree)
         (if (pair? sub-tree)
             (square-tree sub-tree)
             (* sub-tree sub-tree)))
       tree))
directly:
(define (square-tree tree)
  (cond ((null? tree) '())
        ((not(pair? tree)) (* tree tree))
        (else (cons (square-tree (car tree))
                    (square-tree (cdr tree))))))
2.31
(define (tree-map func tree)
  (map (lambda (sub-tree)
         (if (pair? sub-tree)
             (tree-map func sub-tree)
             (func sub-tree)))
       tree))
2.32
(define (subsets s)
  (if (null? s)
      (list '())
      (let ((rest (subsets(cdr s))))
        (append rest (map (lambda (x) (cons (car s) x)) rest)))))
it does works.
when recusive proceess end with nil
rest= (())
m=(map (lambda (x) (cons 3 x)) (())=((3))
rest=(append rest m)=(() (3))
(map (lambda (x) (cons 2 x)) (() (3))=((2) (2 3))
rest=(append rest m)=(() (3) (2) (2 3))
m=(map (lambda (x) (cons 1 x)) (() (3) (2) (2 3)))=((1) (1 3) (1 2) (1 2 3))
(rest (append rest m)=(() (3) (2) (2 3) (1) (1 3) (1 2) (1 2 3))
2.33
(define (map p sequence)
  (accumulate (lambda (x y)(cons (p x) y)) '() sequence))
(define (append seq1 seq2)
  (accumulate cons seq2 seq1))
(define (length sequence)
  (accumulate (lambda (x y) (+ 1 y)) 0 sequence))
2.34
(define (horner-eval x coefficient-sequence)
  (accumulate (lambda (this-coeff higher-terms)(+(* higher-terms x)this-coeff))
              0
              coefficient-sequence))
2.35
(define (count-leaves t)
  (accumulate + 0 (map (lambda (x)(if(pair? x)(count-leaves x)1)) t)))
2.36
(define (accumulate-n op init seqs)
  (if(null? (car seqs))
     '()
     (cons (accumulate op init (map car seqs))
           (accumulate-n op init (map cdr seqs)))))
2.37
(define (matrix-*-vector m v)
  (map (lambda (x) (dot-product v x)) m))
(define (transpose mat)
  (accumulate-n cons '() mat))
(define (matrix-*-matrix m n)
  (let ((cols (transpose n)))
    (map (lambda (x) (matrix-*-vector cols x)) m)))
2.38
满足交换律的操作都可以
2.39
(define (reverse sequence)
  (fold-right (lambda (x y) (append y (list x))) '() sequence))
(define (reverse sequence)
  (fold-left (lambda (x y) (append (list y) x)) '() sequence))
another version:
(define (reverse sequence)
  (fold-left (lambda (x y) (cons y x)) '() sequence))
2.40
(define (unique-pairs n)
  (accumulate append
              '()
              (map (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 (triple n s)
  (filter (lambda (x)(not(null? x)))
          (accumulate append
              '()
              (map (lambda (i)
                     (map (lambda (j)
                            (map (lambda (k) (list i j k))
                                 (enumerate-interval (max 1(-(- s i)j))
                                                     (min (-(- s i)j) n))))
                          (enumerate-interval 1
                                              (min (- s i) n))))
                   (enumerate-interval 1
                                       (min s n))))))
2.42
(define (queen 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 size)))
                         (queen-cols (- k 1))))))
  (queen-cols size))
(define (adjoin-position new-row k rest-of-queens)
  (append  (list(cons new-row k)) rest-of-queens))
(define empty-board '())
(define (safe? k positions)
  (if(null? (cdr positions))
     #t
     (if(or (= (car(car positions)) (car(cadr positions)))
            (= (cdr(car positions)) (cdr(cadr positions)))
            (= (abs(-(cdr(car positions)) (cdr(cadr positions))))
               (abs(-(car(car positions)) (car(cadr positions))))))
        #f
        (safe? k (append (list(car positions))(cddr positions))))))
2.43
前一版本时间复杂度:O(n)
后一版本时间复杂度:O(n^n)
2.44
(define (up-split painter n)
  (if (= n 0)
      painter
      (let ((smaller (up-split painter (- n 1))))
        (below painter (beside smaller smaller)))))
2.45
(define (split f1 f2)
  (define (f painter n)
    (if (= n 0)
        painter
        (let ((smaller (f painter (- n 1))))
          (f1 painter (f2 smaller smaller))))))
2.46
(define (make-vect x y)
  (cons x y))
(define (xcor-vect v)
  (car v))
(define (ycor-vect v)
  (cdr v))
(define (add-vect v1 v2)
  (cons (+ (xcor-vect v1) (xcor-vect v2))
        (+ (ycor-vect v1) (ycor-vect v2))))
(define (sub-vect v1 v2)
  (cons (- (xcor-vect v1) (xcor-vect v2))
        (- (ycor-vect v1) (ycor-vect v2))))
(define (scale-vect s v)
  (cons (* s (xcor-vect v))
        (* s (ycor-vect v))))
2.47
(define (make-frame origin edge1 edge2)
  (list origin edge1 edge2))
(define (origin-frame frame)
  (car frame))
(define (edge1-frame frame)
  (cadr frame))
(define (edge2-frame frame)
  (caddr frame))

(define (make-frame origin edge1 edge2)
  (cons origin (cons edge1 edge2)))
(define (origin-frame frame)
  (car frame))
(define (edge1-frame frame)
  (cadr frame))
(define (edge2-frame frame)
  (cddr frame))
2.48
(define (make-segment v1 v2)
  (cons v1 v2))
(define (start-segment seg)
  (car seg))
(define (end-segment seg)
  (cdr seg))
2.49
(define (make-seg v1x v1y v2x v2y)
  (make-segment (make-vect v1x v1y) (make-vect v2x v2y)))
(define outline
  (segments->painter (list (make-seg 0 0 0 1)
                           (make-seg 0 0 1 0)
                           (make-seg 1 0 1 1)
                           (make-seg 0 1 1 1))))
(define draw-x
  (segments->painter (list (make-seg 0 1 1 0)
                           (make-seg 0 0 1 1))))
(define diamond
  (segments->painter (list (make-seg 0 0.5 0.5 0)
                           (make-seg 0.5 0 1 0.5)
                           (make-seg 1 0.5 0.5 1)
                           (make-seg 0.5 1 0 0.5))))
画个小人,随便画 反正又看不见
(define wave
  (segments->painter (list (make-seg 0.4 0 0.5 0.3)
                           (make-seg 0.5 0.3 0.6 0)
                           (make-seg 0.8 0 0.6 0.5)
                           (make-seg 0.6 0.5 1 0.5)
                           (make-seg 0.6 0.7 1 0.7)
                           (make-seg 0.6 0.7 0.6 1)
                           (make-seg 0.4 1 0.4 0.7)
                           (make-seg 0.4 0.7 0.2 0.7)
                           (make-seg 0.2 0.7 0.2 1)
                           (make-seg 0 1 0 0.5)
                           (make-seg 0 0.5 0.4 0.5)
                           (make-seg 0.4 0.5 0.2 0))))
2.50
(define (flip-horiz painter)
  (transform-painter painter
                     (make-vect 1 0)
                     (make-vect 0 0)
                     (make-vect 1 1)))
(define (rotate180 painter)
  (transform-painter painter
                     (make-vect 1 1)
                     (make-vect 0 1)
                     (make-vect 1 0)))
(define (rotate270 painter)
  (transform-painter painter
                     (make-vect 0 1)
                     (make-vect 1 1)
                     (make-vect 0 0)))
2.51
(define (below p1 p2)
  (let ((aplit-point (make-vect 0 0.5)))
    (let ((paint-up (transform-painter p1
                                       split-point
                                       (make-vect 1 0)
                                       (make-vect 0 0.5)))
          (paint-below (transform-painter p2
                                          (make-vect 0 0)
                                          (make-vect 1 0)
                                          split-point)))
      (lambda (frame)(paint-up frame)(paint-below frame)))))
(define (below p1 p2)
  (rotate90(beside (rotate270 p1)(rotate270 p2))))
2.52
a
(define wave
  (segments->painter (list (make-seg 0.5 0.75 0.45 0.8)
                           (make-seg 0.5 0.75 0.65 0.8)
                           (make-seg 0.4 0 0.5 0.3)
                           (make-seg 0.5 0.3 0.6 0)
                           (make-seg 0.8 0 0.6 0.5)
                           (make-seg 0.6 0.5 1 0.5)
                           (make-seg 0.6 0.7 1 0.7)
                           (make-seg 0.6 0.7 0.6 1)
                           (make-seg 0.4 1 0.4 0.7)
                           (make-seg 0.4 0.7 0.2 0.7)
                           (make-seg 0.2 0.7 0.2 1)
                           (make-seg 0 1 0 0.5)
                           (make-seg 0 0.5 0.4 0.5)
                           (make-seg 0.4 0.5 0.2 0))))
b
(define (corner-split painter n)
  (if (= n 0)
      painter
      (let ((up (rotate90(right-split painter (- n 1))))
            (right (right-split painter (- n 1))))
        (let ((top-left (beside up up))
              (bottom-right (below right right))
              (corner (corner-split painter (- n 1))))
          (beside (below painter top-left)
                  (below bottom-right corner))))))
c
(define (square-limit painter n)
  ((square-of-four split-horiz identity  rotate180 split-vert) (corner-split painter)))

posted on 2010-08-06 19:18  草头菜  阅读(128)  评论(0编辑  收藏  举报

导航