SICP - chapter 2 习题
2018/05/04
2.1
(define (make-rat n d)
(let ((t1 (if (< n 0) -1 1)) ;获取n和d的符号位
(t2 (if (< d 0) -1 1)))
(cond ((= (* t1 t2) 1) (cons (* t1 n) (* t2 d)))
((= t1 -1) (cons n d))
((= t2 -1) (cons (* t2 n) (* t2 d))))))
(displayln (make-rat 1 22))
(displayln (make-rat 1 -22))
(displayln (make-rat -1 22))
(displayln (make-rat -1 -22))
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 x y)
(cons x y))
(define (start-segment s)
(car s))
(define (end-segment s)
(cdr s))
(define (mid-segment s)
(let ((startP (start-segment s))
(endP (end-segment s)))
(let ((x1 (x-point startP))
(x2 (x-point endP))
(y1 (y-point startP))
(y2 (y-point endP)))
(make-point (/ (+ x1 x2) 2) (/ (+ y1 y2) 2)))))
(define (print-point p)
(display "(")
(display (x-point p))
(display ",")
(display (y-point p))
(display ")"))
(define seg1 (make-segment (make-point 1 1) (make-point 3 3)))
(print-point (mid-segment seg1))
2.3
; 需要运行2.2
(define (make-rec p1 p2)
(cons p1 p2))
(define (rec-length p)
(let ((p1 (car p))
(p2 (cdr p)))
(let ((x1 (x-point p1))
(x2 (x-point p2)))
(abs (- x1 x2)))))
(define (rec-width p)
(let ((p1 (car p))
(p2 (cdr p)))
(let ((y1 (y-point p1))
(y2 (y-point p2)))
(abs (- y1 y2)))))
(define (rec-area p)
(* (rec-length p) (rec-width p)))
(define (rec-perimeter p)
(* 2 (+ (rec-length p) (rec-width p))))
(define rec1 (make-rec (make-point 0 0) (make-point 3 2)))
(displayln (rec-area rec1))
(displayln (rec-perimeter rec1))
; 为了使rec-area和rec-perimeter过程不改变,另一种定义方式只要提供rec-length和rec-width接口即可。
2.4
(define (cons1 x y)
(lambda (m) (m x y)))
(define (car1 z)
(z (lambda (p q) p)))
(define (cdr1 z)
(z (lambda (p q) q)))
(car1 (cons1 1 2))
(cdr1 (cons1 1 2))
(cdr1 (cons1 1 2))
; =>
(cdr1 (lambda (m) (m 1 2)))
; =>
((lambda (m) (m 1 2)) (lambda (p q) q))
;=>
((lambda (p q) q) 1 2)
2.5
2.17
(displayln "----2.17")
(define (last-pair l)
(if (null? l)
null
(if (null? (cdr l))
(car l)
(last-pair (cdr l)))))
(last-pair (list 1 2 3))
(last-pair (list))
2.18
(define (reverse l)
(if (null? l)
null
(append (reverse (cdr l)) (list (car l)))))
(reverse (list))
(reverse (list 1))
(reverse (list 1 2 3))
2.20
(define (same-parity x . xs)
(define (same-p n)
(= (remainder x 2) (remainder n 2)))
(if (null? xs)
null
(if (= (remainder x 2) (remainder (car xs) 2))
(cons (car xs) (apply same-parity (cons x (cdr xs))))
(apply same-parity (cons x (cdr xs))))))
(same-parity 111 2 3 4 5 6 7 8 9)
(same-parity 100 2 3 4 5 6 7 8 9)
2.23
(define (for-each f xs)
(if (null? xs)
#t
(begin
(f (car xs))
(for-each f (cdr xs)))))
(for-each (lambda (x) (displayln x)) (list 1 2 3))
2.25
(define x25-1 (list 1 3 (list 5 7) 9))
(car (cdr (car (cdr (cdr x25-1)))))
(define x25-2 (list (list 7)))
(car (car x25-2))
(define x25-3 (list 1 (list 2 (list 3 (list 4 (list 5 (list 6 7)))))))
(car (cdr (car (cdr (car (cdr (car (cdr (car (cdr (car (cdr x25-3))))))))))))
2.26
(define x26 (list 1 2 3))
(define y26 (list 4 5 6))
(append x26 y26)
(cons x26 y26)
(list x26 y26)
2.27
(define (deep-reverse l)
(if (null? l)
null
(if (list? (car l))
(append (deep-reverse (cdr l)) (list (deep-reverse (car l))))
(append (deep-reverse (cdr l)) (list (car l))))))
(deep-reverse '())
(deep-reverse '(1))
(deep-reverse '(1 2))
(deep-reverse (list (list 1 2) (list 3 4)))
(deep-reverse '((1 2) (3 4) 5 6 (7 8)))
2.28
(displayln "二叉树版抽象")
(define (left-tree tree)
(car tree))
(define (right-tree tree)
(car (cdr tree)))
(define (fringe-bin tree)
(cond ((null? tree) null)
((pair? tree) (append
(fringe-bin (left-tree tree))
(fringe-bin (right-tree tree))))
(else (list tree))))
; 多叉树无法work
;(fringe-bin (list (list 1 2 3) (list 4 5 6) (list 7 8) 9))
(define x28 (list (list 1 2) (list 3 4)))
(fringe-bin x28)
(fringe-bin (list x28 x28))
; 多叉树work版
(define (fringe tree)
(cond ((null? tree) null)
((pair? tree) (append
(fringe (car tree))
(fringe (cdr tree))))
(else (list tree))))
(fringe (list (list 1 2 3) (list 4 5 6) (list 7 8) 9))