Add solutions to exercises 2.53-57
This commit is contained in:
parent
2a278157ad
commit
f5131b16db
5 changed files with 219 additions and 0 deletions
7
ex-2.53.txt
Normal file
7
ex-2.53.txt
Normal file
|
@ -0,0 +1,7 @@
|
|||
(list 'a 'b 'c) -> (a b c)
|
||||
(list (list 'george)) -> ((george))
|
||||
(cdr '((x1 x2) (y1 y2))) -> ((y1 y2))
|
||||
(cadr '((x1 x2) (y1 y2))) -> (y1 y2)
|
||||
(pair? (car '(a short list))) -> #f
|
||||
(memq 'red '((red shoes) (blue socks))) -> #f
|
||||
(memq 'red '(red shoes blue socks)) -> (red shoes blue socks)
|
8
ex-2.54.scm
Normal file
8
ex-2.54.scm
Normal file
|
@ -0,0 +1,8 @@
|
|||
#lang sicp
|
||||
|
||||
(define (equal? a b)
|
||||
(cond ((and (pair? a) (pair? b))
|
||||
(and (equal? (car a) (car b)) (equal? (cdr a) (cdr b))))
|
||||
((and (not (pair? a)) (not (pair? b)))
|
||||
(and (eq? a b)))
|
||||
(else #f)))
|
6
ex-2.55.txt
Normal file
6
ex-2.55.txt
Normal file
|
@ -0,0 +1,6 @@
|
|||
When typing (car ''abracadabra), the interpreter will transform the expression
|
||||
into: (car (quote (quote abracadabra))), then it will evaluate.
|
||||
First the symbol car becomes the car procedure, then quote gets evaluated as a
|
||||
special form, which means the surrounded expression should be left
|
||||
unevaluated, so we get something like: (#<car:procedure> (quote abracadabra)),
|
||||
now car gets applied, and we get the expected result.
|
78
ex-2.56.scm
Normal file
78
ex-2.56.scm
Normal file
|
@ -0,0 +1,78 @@
|
|||
#lang sicp
|
||||
|
||||
(define (variable? x) (symbol? x))
|
||||
(define (same-variable? v1 v2)
|
||||
(and (variable? v1) (variable? v2) (eq? v1 v2)))
|
||||
|
||||
(define (=number? exp num) (and (number? exp) (= exp num)))
|
||||
|
||||
(define (make-sum a1 a2)
|
||||
(cond ((=number? a1 0) a2)
|
||||
((=number? a2 0) a1)
|
||||
((and (number? a1) (number? a2))
|
||||
(+ a1 a2))
|
||||
(else (list '+ a1 a2))))
|
||||
|
||||
(define (make-product m1 m2)
|
||||
(cond ((or (=number? m1 0) (=number? m2 0)) 0)
|
||||
((=number? m1 1) m2)
|
||||
((=number? m2 1) m1)
|
||||
((and (number? m1) (number? m2)) (* m1 m2))
|
||||
(else (list '* m1 m2))))
|
||||
|
||||
(define (sum? x) (and (pair? x) (eq? (car x) '+)))
|
||||
(define (addend s) (cadr s))
|
||||
(define (augend s) (caddr s))
|
||||
(define (product? x) (and (pair? x) (eq? (car x) '*)))
|
||||
(define (multiplier p) (cadr p))
|
||||
(define (multiplicand p) (caddr p))
|
||||
|
||||
; for the purposes of our exponentiation exercise, we need to determine whether
|
||||
; the exponent is constant so that we can apply the rule correctly
|
||||
(define (constant? x var)
|
||||
(or (number? x)
|
||||
(and (variable? x) (not (same-variable? x var)))
|
||||
(and (sum? x)
|
||||
(constant? (addend x) var)
|
||||
(constant? (augend x) var))
|
||||
(and (product? x)
|
||||
(constant? (multiplier x) var)
|
||||
(constant? (multiplicand x) var))
|
||||
(and (exponentiation? x)
|
||||
(constant? (base x) var)
|
||||
(constant? (exponent x) var))))
|
||||
|
||||
(define (make-exponentiation b e)
|
||||
(cond ((=number? e 0) 1)
|
||||
((=number? e 1) b)
|
||||
((=number? b 0) 0)
|
||||
((and (number? b) (number? e)) (expt b e))
|
||||
(else (list '** b e))))
|
||||
|
||||
|
||||
(define (exponentiation? x) (and (pair? x) (eq? (car x) '**)))
|
||||
(define (base e) (cadr e))
|
||||
(define (exponent e) (caddr e))
|
||||
|
||||
(define (deriv exp var)
|
||||
(cond ((number? exp) 0)
|
||||
((variable? exp) (if (same-variable? exp var) 1 0))
|
||||
((sum? exp) (make-sum (deriv (addend exp) var)
|
||||
(deriv (augend exp) var)))
|
||||
((product? exp)
|
||||
(make-sum
|
||||
(make-product (multiplier exp)
|
||||
(deriv (multiplicand exp) var))
|
||||
(make-product (deriv (multiplier exp) var)
|
||||
(multiplicand exp))))
|
||||
((exponentiation? exp)
|
||||
(if (constant? (exponent exp) var)
|
||||
(make-product (make-product (exponent exp)
|
||||
(make-exponentiation (base exp)
|
||||
(make-sum
|
||||
(exponent exp)
|
||||
-1)))
|
||||
(deriv (base exp) var))
|
||||
(error "non-constant exponents not yet supported: DERIV" exp)))
|
||||
(else
|
||||
(error "unknown expression type: DERIV" exp))))
|
120
ex-2.57.scm
Normal file
120
ex-2.57.scm
Normal file
|
@ -0,0 +1,120 @@
|
|||
#lang sicp
|
||||
|
||||
; For these exercises, where I'm adding extra functionality to the deriv
|
||||
; system. I chose to build each new feature off of the results of the previous
|
||||
; exercises, rather than the unmodified code.
|
||||
; This might make the solutions a bit more complicated than they have to be
|
||||
|
||||
(define (variable? x) (symbol? x))
|
||||
(define (same-variable? v1 v2)
|
||||
(and (variable? v1) (variable? v2) (eq? v1 v2)))
|
||||
|
||||
(define (=number? exp num) (and (number? exp) (= exp num)))
|
||||
|
||||
(define (not-number? x) (not (number? x)))
|
||||
|
||||
(define (filter predicate sequence)
|
||||
(cond ((null? sequence) nil)
|
||||
((predicate (car sequence))
|
||||
(cons (car sequence)
|
||||
(filter predicate (cdr sequence))))
|
||||
(else (filter predicate (cdr sequence)))))
|
||||
|
||||
; only folds the beginning constants of the top-level expression
|
||||
; e.g. (+ 2 3 5 x) becomes (+ 10 x)
|
||||
; (+ x y z) -> (+ x y z)
|
||||
; (* 2 0 3 x) -> 0
|
||||
; (+ 3 -3 x) -> x
|
||||
(define (fold exp)
|
||||
(if (and (not (sum? exp)) (not (product? exp)))
|
||||
exp ; if you don't know how to fold the exp, just leave it
|
||||
(let* ((op (car exp))
|
||||
(consts (filter number? (cdr exp)))
|
||||
(rest (filter not-number? (cdr exp)))
|
||||
(folded-const (if (eq? op '+)
|
||||
(apply + consts)
|
||||
(apply * consts)))
|
||||
(args (cond ((and (eq? op '*) (= folded-const 0)) '(0))
|
||||
((and (eq? op '*) (= folded-const 1)) rest)
|
||||
((and (eq? op '+) (= folded-const 0)) rest)
|
||||
(else (append (list folded-const) rest)))))
|
||||
(cond ((and (eq? op '+) (= (length args) 0)) 0)
|
||||
((and (eq? op '*) (= (length args) 0)) 1)
|
||||
((= (length args) 1) (car args))
|
||||
(else (append (list op) args))))))
|
||||
|
||||
; make-sum and make-product will be changed so that any arguments which are
|
||||
; sums themselves will be spliced into the list, and all numbers will be placed
|
||||
; in the front and folded
|
||||
(define (make-sum a1 a2)
|
||||
; l1 and l2 are lists to be spliced, if they're not sums, we make them lists
|
||||
; of a list, so effectively, they don't get spliced
|
||||
(let ((l1 (if (sum? a1) (cdr a1) (list a1)))
|
||||
(l2 (if (sum? a2) (cdr a2) (list a2))))
|
||||
(fold (append '(+) l1 l2))))
|
||||
|
||||
(define (make-product m1 m2)
|
||||
(let ((l1 (if (product? m1) (cdr m1) (list m1)))
|
||||
(l2 (if (product? m2) (cdr m2) (list m2))))
|
||||
(fold (append '(*) l1 l2))))
|
||||
|
||||
(define (sum? x) (and (pair? x) (eq? (car x) '+)))
|
||||
(define (addend s) (cadr s))
|
||||
(define (augend s) (if (= (length s) 3)
|
||||
(caddr s)
|
||||
(cons '+ (cddr s))))
|
||||
(define (product? x) (and (pair? x) (eq? (car x) '*)))
|
||||
(define (multiplier p) (cadr p))
|
||||
(define (multiplicand p) (if (= (length p) 3)
|
||||
(caddr p)
|
||||
(cons '* (cddr p))))
|
||||
|
||||
; for the purposes of our exponentiation exercise, we need to determine whether
|
||||
; the exponent is constant so that we can apply the rule correctly
|
||||
(define (constant? x var)
|
||||
(or (number? x)
|
||||
(and (variable? x) (not (same-variable? x var)))
|
||||
(and (sum? x)
|
||||
(constant? (addend x) var)
|
||||
(constant? (augend x) var))
|
||||
(and (product? x)
|
||||
(constant? (multiplier x) var)
|
||||
(constant? (multiplicand x) var))
|
||||
(and (exponentiation? x)
|
||||
(constant? (base x) var)
|
||||
(constant? (exponent x) var))))
|
||||
|
||||
(define (make-exponentiation b e)
|
||||
(cond ((=number? e 0) 1)
|
||||
((=number? e 1) b)
|
||||
((=number? b 0) 0)
|
||||
((and (number? b) (number? e)) (expt b e))
|
||||
(else (list '** b e))))
|
||||
|
||||
|
||||
(define (exponentiation? x) (and (pair? x) (eq? (car x) '**)))
|
||||
(define (base e) (cadr e))
|
||||
(define (exponent e) (caddr e))
|
||||
|
||||
(define (deriv exp var)
|
||||
(cond ((number? exp) 0)
|
||||
((variable? exp) (if (same-variable? exp var) 1 0))
|
||||
((sum? exp) (make-sum (deriv (addend exp) var)
|
||||
(deriv (augend exp) var)))
|
||||
((product? exp)
|
||||
(make-sum
|
||||
(make-product (multiplier exp)
|
||||
(deriv (multiplicand exp) var))
|
||||
(make-product (deriv (multiplier exp) var)
|
||||
(multiplicand exp))))
|
||||
((exponentiation? exp)
|
||||
(if (constant? (exponent exp) var)
|
||||
(make-product (make-product (exponent exp)
|
||||
(make-exponentiation (base exp)
|
||||
(make-sum
|
||||
(exponent exp)
|
||||
-1)))
|
||||
(deriv (base exp) var))
|
||||
(error "non-constant exponents not yet supported: DERIV" exp)))
|
||||
(else
|
||||
(error "unknown expression type: DERIV" exp))))
|
Loading…
Add table
Reference in a new issue