;; 2.1
(define (make-rat n d)
(if (< d 0)
(make-rat (- n) (- d))
(cons n d)))
;; 2.2
(define (make-point x y)
(cons x y))
(define (x-point p)
(car p))
(define (y-point p)
(cdr p))
(define (make-segment start end)
(cons start end))
(define (start-segment s)
(car s))
(define (end-segment s)
(cdr s))
(define (midpoint-segment s)
(let ((a (start-segment s))
(b (end-segment s)))
(make-point (/ (+ (x-point a) (x-point b)) 2)
(/ (+ (y-point a) (y-point b)) 2))))
;; 2.3
; 第一种表示
(define (make-rect mid-point width height)
(cons mid-point
(cons (/ width 2) (/ height 2))))
(define (rect-left r)
(- (x-point (car r)) (car (cdr r))))
(define (rect-right r)
(+ (x-point (car r)) (car (cdr r))))
(define (rect-bottom r)
(- (y-point (car r)) (cdr (cdr r))))
(define (rect-top r)
(+ (y-point (car r)) (cdr (cdr r))))
; 第二种表示
(define (make-rect bottom-left top-right)
(cons bottom-left top-right))
(define (rect-left r)
(x-point (car r)))
(define (rect-right r)
(x-point (cdr r)))
(define (rect-bottom r)
(y-point (car r)))
(define (rect-top r)
(y-point (cdr r)))
; 公用函数
(define (rect-width r)
(- (rect-right r) (rect-left r)))
(define (rect-height r)
(- (rect-top r) (rect-bottom r)))
(define (rect-area r)
(* (rect-width r) (rect-height r)))
(define (rect-perimeter r)
(* 2 (+ (rect-width r) (rect-height r))))
;; 2.4
(define (my-cons x y)
(lambda (m) (m x y)))
(define (my-car z)
(z (lambda (p q) p)))
(define (my-cdr z)
(z (lambda (p q) q)))
;; 2.5
(define (cons-n x y) ; x and y are natural numbers
(if (= x 0)
(if (= y 0) 1
(* 3 (cons x (- y 1))))
(* 2 (cons (- x 1) y))))
(define (car-n z)
(if (= 0 (remainder z 2))
(+ 1 (car (/ z 2)))
0))
(define (cdr-n z)
(if (= 0 (remainder z 3))
(+ 1 (cdr (/ z 3)))
0))
;; 2.6 目前最激动人心的题目
(define zero
(lambda (f) (lambda (x) x)))
(define (add-1 n)
(lambda (f) (lambda (x) (f ((n f) x)))))
(define one
(lambda (f) (lambda (x) (f x))))
(define two
(lambda (f) (lambda (x) (f (f x)))))
(define (add m n)
(lambda (f) (lambda (x) ((m f) ((n f) x)))))
;; 2.7 为什么这么重复的题目啊
(define (make-interval a b) (cons a b))
(define (lower-bound x) (car x))
(define (upper-bound x) (cdr x))
;; 2.8
(define (sub-interval x y)
(make-interval (- (lower-bound x) (upper-bound y))
(- (upper-bound x) (lower-bound y))))
;; 2.9 对于加法,结果的上(下)界即两上(下)界之和,故宽度就是两宽度之和,即(a-b)+(c-d)=(a-c)-(b-d)。减法有相同的结论。对于乘法,(a-b)*(c-d)!=(ac-bd);例如宽度相同的(0,1)、(1,2)、(2,3)两两做乘法运算得到(0,2)、(0,3)、(2,6)三个宽度不同的区间。除法类似。
;; 2.10
(define (div-interval x y)
(if (and (< (lower-bound y) 0) (< 0 (upper-bound)))
(error "Divide by a interval that contains zero -- div-interval")
(mul-interval x
(make-interval (/ 1 (upper-bound y))
(/ 1 (lower-bound y))))))
;; 2.11 其实归结起来只有三种情况:0、1或2个区间包括0。
(define (print-interval i)
(display "[")
(display (lower-bound i))
(display ",")
(display (upper-bound i))
(display "]\n"))
(define (neg-interval i)
(make-interval (- (lower-bound i)) (- (upper-bound i))))
(define (mul-interval x y)
(define (do-it a b c d)
(cond ((< b 0) (neg-interval(do-it (- b) (- a) c d)))
((< d 0) (neg-interval(do-it a b (- d) (- c))))
((and (> a 0) (< c 0)) (do-it c d a b))
((and (< a 0) (> c 0)) (make-interval (* a d) (* b d)))
((and (< a 0) (< c 0)) (make-interval 0 (max (* a c) (* b d))))
((and (> a 0) (> c 0)) (make-interval (* a c) (* b d))))
)
(let ((a (lower-bound x))
(b (upper-bound x))
(c (lower-bound y))
(d (upper-bound y)))
(do-it a b c d)))
;;;
(define (mul-interval-test-cases)
(print-interval (mul-interval (make-interval 2 3) (make-interval 4 5)))
(print-interval (mul-interval (make-interval 2 3) (make-interval -4 5)))
(print-interval (mul-interval (make-interval 2 3) (make-interval -5 -4)))
(print-interval (mul-interval (make-interval -2 3) (make-interval 4 5)))
(print-interval (mul-interval (make-interval -2 3) (make-interval -4 5)))
(print-interval (mul-interval (make-interval -2 3) (make-interval -5 -4)))
(print-interval (mul-interval (make-interval -3 -2) (make-interval 4 5)))
(print-interval (mul-interval (make-interval -3 -2) (make-interval -4 5)))
(print-interval (mul-interval (make-interval -3 -2) (make-interval -5 -4))))
;; 2.12
(define (make-center-percent center percent)
(define delta (/ (* center percent) 100))
(make-interval (- center percent) (+ center percent)))
(define (center i)
(/ (+ (lower-bound i) (upper-bound i)) 2))
(define (percent i)
(abs (* 50 (/ (- (upper-bound i) (lower-bound i)) (center i)))))
(define (print-center-percent i)
(display (center i))
(display "±")
(display (percent i))
(newline)
)
;; 2.13 a(1+b%)*c(1+d%)=ac(1+b%+d%+b%d%)~=ac(1+b%+d%)
;; 2.14 程序将 (div-interval A A) 与 (div-interval A B) 做相同的处理,而没有意识到前者的两个参数并非是独立的。也即,当同一个变量在式子中多次出现时,程序不能意识到它的每次出现必须取相同的值。
(define (check-interval-arithmetic)
(let ((A (make-interval 2 3))
(B (make-interval 2 3)))
(print-interval (div-interval A A))
(print-interval (div-interval A B))))
(define (check-interval-arithmetic-center-percent)
(let ((A (make-center-percent 100.0 3))
(B (make-center-percent 100.0 3)))
(print-center-percent (div-interval A A))
(print-center-percent (div-interval A B))))
;; 2.15 我认为这公式的两个形式是完全等价的,在Alyssa系统上产生的区间限界不同,是由于Alyssa系统的本质缺陷,而非两个形式的优劣。
;; 2.16 当同一个变量在式子中多次出现时,程序不能意识到它的每次出现必须取相同的值。每个变量出现的次数不同会导致Alyssa系统得出的结果不同。无缺陷的区间算术包等价于以下问题:多变量的多项式,每个变量有其取值范围,求多项式的值的取值范围。这个问题属于 Interval Computation 的范畴:http://www.lsi.upc.edu/~robert/mirror/interval-comp/
;; 2.17
(define (last-pair l)
(cond ((null? (cdr l)) l)
(else (last-pair (cdr l)))))
;; 2.18
(define (reverse l)
(define (do-it a b)
(if (null? a) b
(do-it (cdr a) (cons (car a) b))))
(do-it l nil))
;; 2.19
(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? l) (null? l))
(define (except-first-denomination l) (cdr l))
(define (first-denomination l) (car l))
; 根据问题的定义,改变表中元素的顺序不会影响回答。
;; 2.20
(define (same-parity x . s)
(define (iter a)
(if (null? a) nil
(let ((b (iter (cdr a))))
(if (even? (- x (car a)))
(cons (car a) b) b))))
(cons x (iter s)))
;; 2.21
(define (square-list items)
(if (null? items)
nil
(cons (square (car items)) (square-list (cdr items)))))
(define (square-list items)
(map square items))
;; 2.22 第一个程序中,程序从前往后处理things中的元素,却每次把平方后的元素加到answer的头部,故结果的顺序会相反。第二个程序中,当cons的两个参数分别是list和元素时,结果并不是把元素加到list后面。
;; 2.23
(define (for-each f l)
(cond ((not (null? l))
(f (car l))
(for-each f (cdr l)))))
;; 2.24 (1 (2 (3 4)))。
;; 2.25
(car (cdr (car (cdr (cdr '(1 3 (5 7) 9))))))
(car (car '((7))))
(car (cdr (car (cdr (car (cdr (car (cdr (car (cdr (car (cdr '(1 (2 (3 (4 (5 (6 7))))))))))))))))))
;; 2.26
; (1 2 3 4 5 6)
; ((1 2 3) 4 5 6)
; ((1 2 3) (4 5 6))
;; 2.27
(define (deep-reverse t)
(if (list? t)
(map deep-reverse (reverse t))
l))
;; 2.28
(define (fringe t)
(cond ((null? t) nil)
((list? t) (append (fringe (car t)) (fringe (cdr t))))
(else (list t))))
;; 2.29
(define (make-mobile left right)
(list left right))
(define (make-branch length structure)
(list length structure))
; (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 x)
(if (number? x)
x
(+ (total-weight (branch-structure (left-branch x))) (total-weight (branch-structure (right-branch x))))))
; (c)
(define (branch-torque x)
(* (total-weight (branch-structure x))
(branch-length x)))
(define (balanced? x)
(cond ((number? x) true)
(else
(let ((left (left-branch x))
(right (right-branch x)))
(and (= (branch-torque left) (branch-torque right)) (balanced? (branch-structure left)) (balanced? (branch-structure right)))))))
; (d) 只需更改right-branch和branch-structure中的cadr为cdr
;; 2.30
; 直接定义
(define (square-tree t)
(cond ((null? t) nil)
((number? t) (square t))
(else (cons (square-tree (car t)) (square-tree (cdr t))))))
; 使用高阶函数
(define (square-tree t)
(map (lambda (x)
(if (list? x)
(square-tree x)
(square x)))
t))
;; 2.31
(define (tree-map f t)
(map (lambda (x)
(if (list? x)
(tree-map x)
(f x)))
t))
;; 2.32 将子集分为包含与不包含(car s)两种情况。
(define (subsets s)
(if (null? s)
(list nil)
(let ((rest (subsets (cdr s))))
(append rest (map (lambda (x) (cons (car s) x)) rest)))))
;; 2.33
(define (unary-map p sequence)
(accumulate (lambda (x y) (cons (p x) y)) nil sequence))
(define (apppend 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) (+ this-coeff (* x higher-terms)))
0
coefficient-sequence))
;; 2.35
(define (count-leaves t)
(accumulate (lambda (x y)
(+
(if (list? x) (count-leaves x) 1)
y))
0
t))
; 或
(define (count-leaves t)
(accumulate + 0 (map (lambda (x) (if (list? x) (count-leaves x) 1)) t)))
;; 2.36
(define (accumulate-n op init seqs)
(if (null? (car seqs))
nil
(cons (accumulate op init (map car seqs))
(accumulate-n op init (map cdr seqs)))))
;; 2.37
(define (dot-product v w)
(accumulate + 0 (map * v w)))
(define (matrix-*-vector m v)
(map (lambda (x) (dot-product x v)) m))
(define (transpose mat)
(accumulate-n cons nil mat))
(define (matrix-*-matrix m n)
(let ((cols (transpose n)))
(map (lambda (x) (matrix-*-vector cols x)) m)))
;; 2.38
(define (fold-left op initial sequence)
(define (iter result rest)
(if (null? rest)
result
(iter (op result (car rest))
(cdr rest))))
(iter initial sequence))
(define fold-right accumulate)
; 3/2
; 1/6
; (1 (2 (3 ())))
; (((() 1) 2) 3)
; 结合律,以及inital是op的零元。
;; 2.39
(define (reverse sequence)
(fold-right (lambda (x y) (append y (list x))) nil sequence))
(define (reverse sequence)
(fold-left (lambda (x y) (cons y x)) nil sequence))
;; 2.40
(define (flatmap proc seq)
(accumulate append nil (map proc seq)))
(define (unique-pairs n)
(flatmap
(lambda (i)
(map
(lambda (x) (cons x i))
(enumerate-interval 1 (- i 1))))
(enumerate-interval 1 n)))
;; 2.41
(define (pair-sum-no-more-than n)
(flatmap
(lambda (x)
(map (lambda (y) (cons y x))
(enumerate-interval 1 (min (- x 1) (- n x)))))
(enumerate-interval 1 (- n 1))))
(define (triple-sum-is n)
(filter
(lambda (x) (not (or (= (car x) (cadr x)) (= (car x) (caddr x)))))
(map
(lambda (x) (list (- n (car x) (cdr x)) (car x) (cdr x)))
(pair-sum-no-more-than (- n 1)))))
;; 2.42
(define empty-board nil)
(define (safe? k p)
(define (not-same p)
(null? (filter (lambda (x) (= (car p) x)) (cdr p))))
(and
(not-same p)
(not-same (map + p (enumerate-interval 1 k)))
(not-same (map + p (reverse (enumerate-interval 1 k))))))
(define (adjoin-position n k r)(cons n r))
(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))
;; 2.43 原程序中每个 (queen-cols k) 只需调用一次,而这个程序中,为了计算 (queen-cols k),需要调用 k 次 (queen-cols (- k 1));大约需要k!T的时间。
;; 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 combo1 combo2)
(lambda (painter n)
(if (= n 0)
painter
(let ((smaller (up-split painter (- n 1))))
(combo1 painter (combo2 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 v w)
(make-vect (+ (xcor-vect v) (xcor-vect w))
(+ (ycor-vect v) (ycor-vect w))))
(define (sub-vect v w)
(make-vect (- (xcor-vect v) (xcor-vect w))
(- (ycor-vect v) (ycor-vect w))))
(define (scale-vect s v)
(make-vect (* 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 (edge2-frame frame)
(cddr frame))
;; 2.48
(define (make-segment v w)
(cons v w))
(define (start-segment s)
(car s))
(define (end-segment s)
(cdr s))
;; 2.49
; (a)
(define outline-painter
(let ((left-bottom (make-vect 0 0))
(left-top (make-vect 0 1))
(right-bottom (make-vect 1 0))
(right-top (make-vect 1 1)))
(segments->painter (list
(make-segment left-top left-bottom)
(make-segment left-bottom right-bottom)
(make-segment right-bottom right-top)
(make-segment right-top left-top)))))
; (b)
(define X-painter
(let ((left-bottom (make-vect 0 0))
(left-top (make-vect 0 1))
(right-bottom (make-vect 1 0))
(right-top (make-vect 1 1)))
(segments->painter (list
(make-segment left-bottom right-top)
(make-segment left-top right-bottom)))))
; (c)
(define diamond-painter
(let ((bottom (make-vect 0.5 0))
(left (make-vect 0 0.5))
(top (make-vect 0.5 1))
(right (make-vect 1 0.5)))
(segments->painter (list
(make-segment bottom left)
(make-segment left top)
(make-segment top right)
(make-segment right bottom)))))
; (d) 来源 http://d.hatena.ne.jp/laughing/20081115/1226737187,有修正
(define wave
(let ((p0 (make-vect 0.4 1.0))
(p1 (make-vect 0.35 0.8))
(p2 (make-vect 0.4 0.6))
(p3 (make-vect 0.3 0.6))
(p4 (make-vect 0.15 0.55))
(p5 (make-vect 0 0.8))
(p6 (make-vect 0 0.6))
(p7 (make-vect 0.15 0.4))
(p8 (make-vect 0.3 0.55))
(p9 (make-vect 0.35 0.5))
(p10 (make-vect 0.3 0))
(p11 (make-vect 0.4 0))
(p12 (make-vect 0.5 0.3))
(p13 (make-vect 0.6 0))
(p14 (make-vect 0.7 0))
(p15 (make-vect 0.6 0.45))
(p16 (make-vect 1.0 0.2))
(p17 (make-vect 1.0 0.4))
(p18 (make-vect 0.8 0.6))
(p19 (make-vect 0.6 0.6))
(p20 (make-vect 0.65 0.8))
(p21 (make-vect 0.6 1.0)))
(segments->painter
(list
(make-segment p0 p1)
(make-segment p1 p2)
(make-segment p2 p3)
(make-segment p3 p4)
(make-segment p4 p5)
(make-segment p6 p7)
(make-segment p7 p8)
(make-segment p8 p9)
(make-segment p9 p10)
(make-segment p11 p12)
(make-segment p12 p13)
(make-segment p14 p15)
(make-segment p15 p16)
(make-segment p17 p18)
(make-segment p18 p19)
(make-segment p19 p20)
(make-segment p20 p21)))))
;; 2.50
(define (flip-horiz painter)
(transform-painter painter
(make-vect 1 0)
(make-vect 0 0)
(make-vect 1 1)))
(define (rotate-180 painter)
(transform-painter painter
(make-vect 1 1)
(make-vect 0 1)
(make-vect 1 0)))
(define (rotate-270 painter)
(transform-painter painter
(make-vect 0 1)
(make-vect 0 0)
(make-vect 1 1)))
;; 2.51
(define (below painter1 painter2)
(let ((paint-bottom
(transform-painter painter1
(make-vect 0 0)
(make-vect 1 0)
(make-vect 0 0.5)))
(paint-top
(transform-painter painter2
(make-vect 0 0.5)
(make-vect 1 0.5)
(make-vect 0 1))))
(lambda (frame)
(paint-bottom frame)
(paint-top frame))))
(define (below painter1 painter2)
(rotate-270 (beside (rotate-90 painter1) (rotate-90 painter2))))
;; 2.52
; (a) 略
; (b)
(define (corner-split painter n)
(if (= n 0)
painter
(let ((up (up-split painter n))
(right (right-split painter n)))
(let ((top-left up)
(bottom-right right)
(corner (corner-split painter (- n 1))))
(beside (below painter top-left)
(below bottom-right corner))))))
; (c)
(define (square-limit painter n)
(let ((combine4 (square-of-four identity flip-horiz
flip-vert rotate180)))
(combine4 (corner-split painter n)))) |
December 12, 2008
· Filed under 程序园
sqybi Said,
December 31, 2008 @ 20:42
a dream to host…我记得我以前用这个theme的时候经常有各种各样的bug…
Leo Said,
January 17, 2009 @ 17:53
Hi, 翼若垂天
我是和你一样的大一生,无意间来到你的博客,
看到你大一就拿到 acm 金牌特别羡慕,
我其实对编程也很感兴趣,只不过我们这边C++的教学质量实在是不高,因此有一种有心无力的感觉,因为不知道从什么地方开始。
所以我想问问你觉得有什么建议如果要学好C++的话?有什么书好看?
You should have my email address when I submitted this comment, so feel free to contact via my email address, I will be looking forward to your comment…..
RoMax Said,
January 30, 2009 @ 22:27
话说。。你是不是可以考虑着首页不要那么长。。
Li Said,
February 4, 2009 @ 02:39
Hi,
我无意中找到了你的SICP习题解答,真是喜出忘外,同时也羡慕你在这方面的能力。
如果你愿意的话,请跟我联系。我还想问你怎么能够找到SICP的教学光碟呢。
Best Withes
Li
nehzilrz Said,
February 27, 2009 @ 17:03
Hi,dd牛
我是一个正在准备省选的OIer
希望能与你进行一下关于此的交流
mail:nehzilrz@yeah.net
qq :248423750
Bi Ran Said,
March 13, 2009 @ 16:46
我们上学期的编程课学的就是scheme,教材也是SICP
一学期的课学的太少了
不过这东西学了用处不大……主要是长长见识
wecing Said,
July 5, 2009 @ 19:24
dd你怎么消失了……
flyink Said,
September 27, 2009 @ 12:33
我来是想问下~~WORDPRESS租什么样的空间比较好啊~~~
116 Said,
October 23, 2009 @ 02:45
请问以下问题楼主有什么高见:
define the set A={(x,y)belong to R^2,X^2+y^2 小于等于1}, and the point b=(3,3)belong to R^2. find all hyperplanes separating the set A and the point b.
Hint:
a)provide a graphic sketch of the problem
b)break the problem into three or more simpler subproblems
c)slove these subproblems one by one,starting with the simplest
Phil Said,
January 7, 2010 @ 17:18
dd牛您2009年一年都没有更新…
MaoYu Said,
February 12, 2010 @ 21:50
全部阅览完毕。
2009年估计是DD静心学习的一年。
我也大一,曾今的OIer,很想参加ACM。不过学校以前好像没有人参加过,我想问问怎么报名啊?很复杂吗?我自己可以负责吗?