Structure and Interpretation of Computer Programs

Class length: 13 weeks. Start anytime.

Creator: kday

Status: Established

Assignment 1

Exercises in 1.2

Do the ODD exercises (1.9 through 1.27) in section 1.2.

Exercise 1.23 requires output from exercise 1.22. You have the option to either do both or neither.

That's a total of 9 - 10 problems. Last week's homework was 8 problems, so this should take just a little bit longer. If you have extra time, you can do the even exercises also and you'll get a ninja star.

Homework Submissions (12 total):

GDR (Self-grade: Could be better)
Submitted 8 months ago

1.11

(define (f-iter n a b c i)
  (if (= (+ 1 n) i)
      a
      (f-iter n (+ a b b c c c) a b (+ 1 i))
      )
  )

(define (f n) (if (< n 3) 1 (f-iter n 1 1 1 3)))
Permalink
yangsx (Self-grade: Pretty good)
Submitted 7 months ago

Just the first two exercises.

Ex 1.9

First version

(+ 4 5)

(inc (+ 3 5))

(inc (inc (+ 2 5)))

(inc (inc (inc (+ 1 5))))

(inc (inc (inc (inc (+ 0 5)))))

(inc (inc (inc (inc 5))))

(inc (inc (inc 6)))

(inc (inc 7))

(inc 8)

9

This is a recursive process.

Second version

(+ 4 5)

(+ 3 6)

(+ 2 7)

(+ 1 8)

(+ 0 9)

9

This is an iterative process.

Ex 1.10

(A 1 10) ; 1024

(A 2 4) ; 65536

(A 3 3) ; 65536

f calculates 2n, g calculates 2^n, and h calculates (2^(2^(2^...2))) with 2 occurring n times.

Permalink

Comments:

kday
7 months ago

Looks good.

Sign up or log in to comment

meowzero (Self-grade: Could be better)
Submitted 7 months ago

I started this HW early, so I did some even numbered problems before I knew about the odd numbered only problems.

Exercise 1.9

(+ 4 5)

(if (= 4 0) 5 (inc (+ (dec 4) 5))))

(inc (+ 3 5))

(inc (if (= 3 0) 5 (inc (+ (dec 3) 5)))))

(inc (inc (+ 2 5)))

(inc (inc (if (= 2 0) 5 (inc (+ (dec 2) 5)))))

(inc (inc (inc (+ 1 5))))

(inc (inc (inc (if (= 1 0) 5 (inc (+ (dec 1) 5))))))

(inc (inc (inc (inc (+ 0 5)))))

(inc (inc (inc (inc (if (= 0 0) 5 (inc (+ (dec 0) 5)))))))

(inc (inc (inc (inc 5))))

(inc (inc (inc 6)))

(inc (inc 7))

(inc 8)

9 Recursive

(+ 4 5)

(if (= 4 0) 5 (+ (dec 4) (inc 5)))

(+ (dec 4) (inc 5)))

(+ 3 6)

(if (= 3 0) 6 (+ (dec 3) (inc 6)))

(+ (dec 3) (inc 6))

(+ 2 7)

(if (= 2 0) 7 (+ (dec 2) (inc 7)))

(+ (dec 2) (inc 7))

(+ 1 8)

(if (= 1 0) 8 (+ (dec 1 ) (inc 8)))

(+ (dec 1) (inc 8))

(+ 0 9)

(if (= 0 0) 9 (+ (dec 0) (inc 9)))

9 Iterative

Exercise 1.10

(A 1 10) = 1024

(A 2 4) = 65536

(A 3 3 ) = 65536

(f n) = 2n

(g n) = 2^n

(h n) = 2^(h (n-1))

Exercise 1.15

a) 5

b) O(log(a)) for both space and time

Exercise 1.19

??

Exercise 1.20

run forever for normal order? 4 times for applicative order

Exercise 1.21

199 -> 199

1999 -> 1999

19999 -> 7

1.23

??

Exercise 1.25

Yes, she is correct. Both methods should give the same answers. She is correct. But I don't know if this would serve well for our fast prime tester.

; Exercise 1.11
(define (f n)
    (if (< n 3) n
        (+ (f (- n 1)) (* 2 (f (- n 2))) (* 3 (f (- n 3))))))


(define (g n)
    (g-iter 2 1 0 n))

(define (g-iter a b c count)
  (if (< count 3) a
      (g-iter (+ a (* 2 b) (* 3 c)) a b (- count 1))))

; Exercise 1.12

(define (pascals-triangle row col)
  (cond ((or (= col 0) (> col row)) 0)
        ((= col row ) 1)
        ((= row 1) 1)
        (else (+ (pascals-triangle (- row 1) (- col 1))
                 (pascals-triangle (- row 1) col)))))
 

; Exercise 1.16
(define (fast-iter-exp b n)
  (iter b n 1))

(define (iter b n a)
  (cond ((= n 0) a)
        ((even? n) (iter (square b) (/ n 2) a))
        (else (* b (iter b (- n 1) a)))))

; Exercise 1.17
(define (double n)
  (+ n n))

(define (halve n)
  (/ n 2))

(define (* a b)
  (cond ((= b 0) 0)
        ((even? b) (* (double a) (halve b)))
        (else (+ a (* (double a) (halve (- b 1)))))))

; Exercise 1.27
(define (square x) (* x x)) 
  
(define (expmod base exp m) 
  (cond ((= exp 0) 1) 
        ((even? exp) 
         (remainder (square (expmod base (/ exp 2) m)) m)) 
        (else 
          (remainder (* base (expmod base (- exp 1) m)) m))))         
  
(define (fermat-test n)
  (define (fermat-iter n a)
    (cond ((= n a) #t)
          ((= (expmod a n n) a ) (fermat-iter n (+ a 1)))
          (else #f)))
  (fermat-iter n 1))

;The Carmichael numbers do not fool it. So something is wrong.
Permalink

Comments:

kday
7 months ago

Nice work!

lmarburger
2 months ago

I was stuck on example 1.11 so I came here to see how other people solved it. I came across your solution and it finally made sense. Thanks!

However, there's a slight bug in that if n < 2, g will always return 2 instead of n. Below is what I came up with which I know isn't perfect, but it seems to return the correct answer.

(define (g n)
  (if (< n 3)
    n
    (g-iter 2 1 0 (- n 2))))

(define (g-iter a b c count)
  (if (= count 0)
    a
    (g-iter (+ a (* 2 b) (* 3 c)) a b (- count 1))))

Sign up or log in to comment

npolyspace (Self-grade: Pretty good)
Submitted 7 months ago

exercise 1.9

Recursive: 1: (+ 4 5) -> (inc (+ 3 5)) -> (inc (inc (+ 2 5))) -> (inc (inc (inc (+ 1 5)))) -> (inc (inc (inc (inc (+ 0 5))))) then start evaluating + and inc.

tail-recursive 2: (+ 4 5) -> (+ 3 6) -> (+ 2 7) -> (+ 1 8) -> (+ 0 9)=9.

Exercise 1.10. The following procedure computes a mathematical function called Ackermann's function.

(A 1 10) 1024

(A 2 4) 65536

(A 3 3) 65536

(define (f n) (A 0 n)) ; (f n) is (* n 2)

(define (g n) (A 1 n)) ; (g n) is (2^n)

(define (h n) (A 2 n)) ; (h n) is the expression 2 raised to the power 2 raised to the power ... raised to the power 2. (n occurrences of raising to the power 2)

Exercise 1.11.

Exercise 1.12.

Exercise 1.13. Prove that Fib(n) is the closest integer to n/5, where = (1 + 5)/2. Hint: Let = (1 - 5)/2. Use induction and the definition of the Fibonacci numbers (see section 1.2.2) to prove that Fib(n) = (n - n)/5.

following hint: first note that ((1+sqrt(5))/2)^(n+1)=1/4(1+sqrt(5)^(n-1)(1+5+2sqrt(5))/2^(n-1) and ((1-sqrt(5))/2)^(n+1)=1/4(1-sqrt(5)^(n-1)(1+5-2sqrt(5))/2^(n-1) phi^n-psi^n+ psi^(n-1)-psi(n-1)= (0.25(1+ 1/2+1/2sqrt(5))+0.25(1+ 1/2-1/2sqrt(5))) /2^(n-1)=phi^(n+1)-psi^(n+1)

Exercise 1.14. Draw the tree illustrating the process generated by the count-change procedure of section 1.2.2 in making change for 11 cents. What are the orders of growth of the space and number of steps used by this process as the amount to be changed increases?

(count-change 11) (cc 11 5) (+ (cc 11 4) (cc -39 5)) (+ (cc 11 3) (cc -14 4)) (+ (cc 11 2) (cc 1 3)) (+ (+(cc 11 1) (cc 6 2)) (+ (cc 1 2) (cc -9 3))) (+ (+(cc 11 0) (cc 10 1)) (+ (cc 6 1) (cc 1 2)) (+ (cc 1 1) (cc -4 2)))
(+ (+(cc 10 0)(cc 9 1)) (+(cc 6 0)(cc 5 1) (+(cc 0 2)(cc 1 1)) 1)) (+ (+(cc 9 0)(cc 8 1)) (+(cc 5 0)(cc 4 1) 1 1)) (+ (+(cc 8 0)(cc 7 1)) (+(cc 4 0)(cc 3 1) 1 1)) (+ (+(cc 7 0)(cc 6 1)) (+(cc 3 0)(cc 2 1) 1 1)) (+ (+(cc 6 0)(cc 5 1)) (+(cc 2 0)(cc 1 1) 1 1)) (+ (+(cc 5 0)(cc 4 1)) (+(cc 1 0)(cc 0 1) 1 1)) (+ (+(cc 4 0)(cc 3 1)) (+0 1) 1 1)) (+ (+(cc 3 0)(cc 2 1)) 1 1 1)) (+ (+(cc 2 0)(cc 1 1)) 1 1 1)) (+ (+0 1 ) 1 1 1)) (+ 1 1 1 1))

Exercise 1.15. The sine of an angle (specified in radians) can be computed by making use of the approximation sin x x if x is sufficiently small, and the trigonometric identity

to reduce the size of the argument of sin. (For purposes of this exercise an angle is considered ``sufficiently small'' if its magnitude is not greater than 0.1 radians.) These ideas are incorporated in the following procedures:

a. How many times is the procedure p applied when (sine 12.15) is evaluated? sine recurses down by factors of 3 to 0.1 so sine is evaluated at each of: 12.15,4.05,1.35,0.45,0.15,0.05 values. So P is evaluated six times.

b. What is the order of growth in space and number of steps (as a function of a) used by the process generated by the sine procedure when (sine a) is evaluated? the order of growth is log(a) for the number of steps. The size is likely to also be order log(a), because tail call optimization will not be able to remove the call to p on the return of the recursive call.

Exercise 1.17. I suppose calling this fast-mult is misleading. I put in an if case to handle negative numbers.

1.19 T_pq(a,b)-> bq+aq+ap,bp+aq so TT-> (bp+aq)q+(bq+aq+ap)(q+p), (bp+aq)p+(bq+aq+ap)q = pq(b+b+a+a)+qq(a+b+a)+app, pq(a+a)+ppb+qq(b+a) =a(2pq+2qq+pp)+b(2pq+qq), a(2pq+qq)+b(pp+qq) =b(2pq+qq)+a(2pq+2qq)+a(pp+qq),b(pp+qq)+a(2pq+2qq) so q'=2pq+qq, p'=pp+qq

exercise 1.21 Use the smallest-divisor procedure to find the smallest divisor of each of the following numbers: 199, 1999, 19999. I got 199,1999,7

;Exercise 1.10. 
(define (A x y)
  (cond ((= y 0) 0)
        ((= x 0) (* 2 y))
        ((= y 1) 2)
        (else (A (- x 1)
                 (A x (- y 1))))))


;Exercise 1.11. 
(define (ex1p11r n)
  (cond ((< n 3) n)
        (else (+ (ex1p11r (- n 1))
                 (* 2 (ex1p11r (- n 2)))
		 (* 3 (ex1p11r (- n 3)))))))		 


(define (ex1p11i n)
(if (< n 3) n	
  (ex1p11-iter 0 1 2 n)))

(define (ex1p11-iter a b c count)
  (if (= count 2)
      c
      (ex1p11-iter b c (+ c (* 2 b) (* 3 a)) (- count 1))))


Exercise 1.12. 
(define (pascal r c)
(cond ((= c 1) 1)
((= r c) 1)
(else (+ (pascal (- r 1) c) (pascal (- r 1) (- c 1))))))



(define (cube x) (* x x x))
(define (p x) (- (* 3 x) (* 4 (cube x))))
(define (sine angle)
   (if (not (> (abs angle) 0.1))
       angle
       (p (sine (/ angle 3.0)))))


;Exercise 1.17. 
(define (double x)(* x 2))
(define (halve x)(/ x 2))
(define (fast-mult a b)
  (cond ((= a 0) 0)
        ((even? a) (double (fast-mult (/ a 2) b)))
        (else (if (> a 0) (+ b (fast-mult (- a 1) b))
		  (- (fast-mult (+ a 1) b) b)))))

;1.19
(define (fib n)
  (fib-iter 1 0 0 1 n))
(define (fib-iter a b p q count)
  (cond ((= count 0) b)
        ((even? count)
         (fib-iter a
                   b
                   (+ (* p p)   (* q q))      ; compute p'
                   (+ (* 2 p q) (* q q))      ; compute q'
                   (/ count 2)))
        (else (fib-iter (+ (* b q) (* a q) (* a p))
                        (+ (* b p) (* a q))
                        p
                        q
                        (- count 1)))))


;exercise 1.21 
(define (square x) (* x x))
(define (smallest-divisor n)
  (find-divisor n 2))
(define (find-divisor n test-divisor)
  (cond ((> (square test-divisor) n) n)
        ((divides? test-divisor n) test-divisor)
        (else (find-divisor n (+ test-divisor 1)))))
(define (divides? a b)
  (= (remainder b a) 0))



Permalink

Comments:

kday
7 months ago

Great job! Looks good.

Sign up or log in to comment

dtmetz (Self-grade: Pretty good)
Submitted 7 months ago

1.13 Couldn't figure this out - wikipedia has a proof, but I don't fully follow.

1.15 a) sin 12.15 12.15/3 = 4.05/3 = 1.35/3 = 0.45/3 = .15/3 = 0.05 1+ 2+ 3+ 4+ 5 = 5 times

b) O(log(n)) - growth O(log(n)) - steps We are dividing the angle in half each time iteration

1.21 199 1999 7

1.25 Yes, this would work. In expmod we checking the same conditions, then calling remainder on it.

This is better too, because if we had a faster way of calculating the exponent of a number we could just plug in another version with out touching expmod.

;1.9
(+ 4 5)
((inc (+ (4-1) 5))))
(inc (+ 3 5))
(inc (inc (+ 2 5)))
(inc (inc (inc (+ 1 5))))
(inc (inc (inc (inc (+ 0 5))))
(inc (inc (inc (inc (5))))))
(inc (inc (inc (6))))
(inc (inc 7)))
(inc 8))
9
This is recursive

and

(+ 4 5)
(+ 3 6)
(+ 2 7)
(+ 1 8)
(+ 0 9)
9
This is iterative

; 1.11
; Recursive
(define (f n)
  (cond ((< n 3) 3)
        (else (+ (f (- n 1)) 
                 (* 2 (f (- n 2))) 
                 (* 3 (f (- n 3)))))))


; Iterative
(define (f2 n)
  (f-iter 3 3 3 n))

(define (f-iter a b c count)
  (if (= count 0)
      c
      (f-iter (+ a (* 2 b) (* 3 c)) a b (- count 1))))


1.17
(define (double n) 
  (+ n n))

(define (half n) 
  (/ n 2))

(define (even2? n) 
  (= (remainder n 2) 0))

(define (fast* a b)
  (cond ((= a 0) 0)
        ((= b 0) 0)
        ((even2? b) (fast* (double a) (half b)))
        (else (+ a (fast* a (- b 1))))))

1.19
(define (fib n) 
  (fib-iter 1 0 0 1 n))

(define (fib-iter a b p q count) 
  (cond ((= count 0) b)
        ((even? count) 
         (fib-iter a
                   b
                   (+ (* p p) (* q q ))  ; compute p'
                   (+ (* 2 p q) (* q q)) ; compute q'
                   (/ count 2))) 
        (else (fib-iter (+ (* b q) (* a q) (* a p))
                        (+ (* b p) (* a q)) 
                        p
                        q
                        (- count 1)))))

1.27
(define (expmod base exp m) 
  (cond ((= exp 0) 1)
        ((even? exp) 
         (remainder (square (expmod base (/ exp 2) m)) m))
        (else (remainder (* base (expmod base (- exp 1) m)) m))))

(define (fermat-test-all n)
  (define (try-it a)
    (not (= (expmod a n n) a)))
  
  (define (fermat-iter n count)
    (cond ((= n count) (= 1 0))
          ((try-it count) (= 1 1))
          (else (fermat-iter n (+ count 1)))))
  
  (fermat-iter n 2))
  
; Returns true if any numbers satisfy Fermat's Test
; Sanity Check
(display "150 ")
(fermat-test-all 150)

; Carmichael numbers
(display "561 " )
(fermat-test-all 561)

(display "1105 ")
(fermat-test-all 1105)

(display "1729 ")
(fermat-test-all 1729)

(display "2465 ")
(fermat-test-all 2465)

(display "6601 ")
(fermat-test-all 6601)

Output:
150 #t
561 #f
1105 #f
1729 #f
2465 #f
6601 #f
          
Permalink

Comments:

kday
7 months ago

Nice work!

Sign up or log in to comment

fcshel (Self-grade: Pretty good)
Submitted 7 months ago

I'll add the rest when I get to it.

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;Ex1.9
;;
;;Procedure 1
(+ 4 5)
(inc (+ 3 5))
(inc (inc (+ 2 5)))
(inc (inc (inc (+ 1 5))))
(inc (inc (inc (inc (+ 0 5)))))
(inc (inc (inc (inc 5))))
(inc (inc (inc 6)))
(inc (inc 7))
(inc 8)
9

;;This is O(a) in time and space, and is thus recursive

;;Procedure 2
(+ 4 5)
(+ 3 6)
(+ 2 7)
(+ 1 8)
(+ 0 9)
9

;;This is O(a) in time and O(1) in space.  Iterative

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;Ex1.10

(A 1 10)
(A 0 (A 1 9))
(A 0 (A 0 (A 1 8)))
.
.
.
(A 0 (A 0 (A 0 (A 0 (A 0 (A 0 (A 0 (A 0 (A 0 (A 1 1))))))))))
(A 0 (A 0 (A 0 (A 0 (A 0 (A 0 (A 0 (A 0 (A 0 2)))))))))
(A 0 (A 0 (A 0 (A 0 (A 0 (A 0 (A 0 (A 0 2^2))))))))
.
.
.
2^10
1024

(A 2 4)
(A 1 (A 2 3))
2^(A 2 3)
2^(A 1 (A 2 2))
2^(2^(A 2 2))
2^(2^(A 1 (A 2 1)))
2^2^2^2
65536
;; We will write this function at f(2,n) = 2_1^2_2^...^2_n so it becomes
f(2 4)
(A 3 3)
(A 2 (A 3 2))
f(2 (A 3 2))
f(2 (A 2 (A 3 1)))
f(2 f(2 (A 3 1)))
f(2 f(2 2)))
(2^2^...^2_(2^2))
(2^2^2^2)
65536

;;(f n) computes 2n
;;(g n) computes 2^n
;;(h n) computes 2\{up_arrow}^{2}n or the tetration of m with n

;;The function given here is slightly different than Ackermann's
;;function seen elsewhere (check wolfram and wiki) but seems cleaner

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;Ex 1.11

;;Recursive
(define (f n)
  (if (< n 3)
      n
      (+ (f (- n 1))
         (* 2 
            (f (- n 2)))
         (* 3
            (f (- n 3))))
      )
  )


;;Iterative
(define (f_iter n)
  (define (f_n fn-1 fn-2 fn-3)
      (+ fn-1
         (* 2
            fn-2)
         (* 3
            fn-3)))
  (define (iter fn-1 fn-2 fn-3 count)
    (if (= count n)
        (f_n fn-1 fn-2 fn-3)
        (iter (f_n fn-1 fn-2 fn-3)
              fn-1
              fn-2 (inc count))))
  (if (< n 3)
      n
      (iter 2 1 0 3)))

;;For n = 20, the recursive program can almost keep up, but for anything
;;over that, the difference is obvious, and by n = 50 they are
;;remarkable.

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;Ex 1.12

(define (pascal row element)
  (if (or (= element 1) (= row element))
      1
      (+ (pascal (dec row)
                 (dec element))
         (pascal (dec row)
                 element))))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;Ex 1.13

;;Fib(N) = \frac{\phi^N-\psi^N }{\sqrt{5}} clearly holds for Fib(0) and
;;Fib(1).  Now checking Fib(N) = Fib(N-1)+Fib(N-2), Fib(N) =
;;\frac{\phi^{N-1}-\psi^{N-1}}{\sqrt{5}}+\frac{\phi^{N-2}-\psi^{N-2}}{\sqrt{5}}
;;= \frac{(\phi^{N-1}+\phi^{N-2})-(\psi^{N-1}+\psi^{N-2})}{\sqrt{5}}.  As
;;\psi and \phi are both roots of the equation x^2-x-1 = 0, we can
;;multiply by x^{N-2} and rearrange to get x^N = x^{N-1} + x^{N-2}, thus
;;showing:
;;\frac{\phi^N-\psi^N }{\sqrt{5}} =
;;\frac{\phi^{N-1}-\psi^{N-1}}{\sqrt{5}}+\frac{\phi^{N-2}-\psi^{N-2}}{\sqrt{5}}.

;;Now, as \abs{\psi}<1, \abs{\frac{\psi}{\sqrt{5}}}<\frac{1}{2}.  As
;;\abs{\phi^N} is a positive decreasing function, for all N,
;;\frac{\psi^N}{\sqrt{5}}< \frac{1}{2}.  Thus \frac{\phi^N}{\sqrt{5}} is
;;the closest integer to Fib(N) and we can calculate Fib(N)  by
;;rounding this function.

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;Ex 1.14

;;The tree diagram is large enough that I think I will skip drawing it
;;here.  I originally throught that this was O(e^amount) in time as the
;;branches approximately double each step.  However, Bill the Lizard gives
;;a nice discussion of this on his blog in which he shows that the
;;branching is moderated by the number of coins available, and thus,
;;exponential in that.  The program is actually O(amount^5).  In space is
;;is O(amount)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;Ex 1.15

;;a. 12.15/3^5 = 0.05 so (p x) is called 5 times.

;;b. Angle/3^n ~0.1, so n~ ln(angle/0.1/3).  Thus n~ln(angle).  As n
;;counts both the number of steps and the number of calls to (p x), this
;;program is O(log(angle)) in space and time.

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;Ex 1.16

;;We define the transform a b n (n even)-> a (square b) (/ n 2)
;;				(n odd)-> (* b a) b (dec n)
;;This preserves the product a*b^n and will give us an process which is
;;O(1) in space and still O(log(n)) in time.

(define (exp-iter base exp)
  (define (iter a b n)
    (cond ((= n 0) a)
          ((even? n)
           (iter a (square b) (/ n 2)))
          (else (iter (* b a) b (dec n)))))
  (iter 1 base exp))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;Ex 1.17

(define (fast-mult a b)
  (cond ((= b 1) a)
        ((even? b)
         (double (fast-mult a (halve b))))
        (else (+ a (fast-mult a (- b 1))))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;Ex 1.18

;; For state variables a b c, equation of state is ab+c and the
transform is 
;;		 a b c (b even)-> (double a) (halve b) c
;;		 a b c (b odd)-> a (dec b) (+ c a)

;; do this until (= b 1) and return (+ a c)

(define(fast-mult-iter a b)
  (define (iter x y z)
    (cond ((= y 1) (+ x z))
          ((even? y) (iter (double x) (halve y) z))
          (else (iter x (dec y) (+ z x)))))
  (iter a b 0))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;Ex 1.19

(define (fib-iter a b p q count)
  (cond ((= count 0) b)
        ((even? count)
         (fib-iter a
                   b
                   (+ (square p) (square q))
                   (+ (square q) (* 2 p q))
                   (/ count 2)))
        (else (fib-iter (+ (* b p) (* a q) (* a p))
                        (+ (* b p) (* a q))
                        p
                        q
                        (- count 1)))))

;;Admittedly, I don't really understand this transformation.  Does
;;anyone have any insight into this?

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;Ex 1.20

;;Normal-order
(gcd 206 40)
(gcd 40 (remainder 206 40))
(remainder 206 40)->6
(gcd (remainder 206 40)
     (remainder 40 (remainder 206 40)))
(remainder 40 (remainder 206 40))->4
(gcd (remainder 40 (remainder 206 40))
     (remainder (remainder 206 40) (remainder 40 (remainder 206 40))))
(remainder (remainder 206 40)
           (remainder 40 (remainder 206 40)))->2
(gcd (remainder (remainder 206 40) (remainder 40 (remainder 206 40)))
     (remainder (remainder 40 (remainder 206 40))
                (remainder (remainder 206 40)
		           (remainder 40 (remainder 206 40))))
(remainder (remainder 40 (remainder 206 40))
           (remainder (remainder 206 40)
           (remainder 40 (remainder 206 40))))->0
(remainder (remainder 206 40)
	   (remainder 40 (remainder 206 40)))->2
;;Counting up the (remainder ) calls gives 18

;;Applicative order

(gcd 206 40)
(gcd 40 (remainder 206 40))
(gcd 40 6)
(gcd 6 (remainder 40 6))
(gcd 6 4)
(gcd 4 (remainder 6 4))
(gcd 4 2)
(gcd 2 (remainder 4 2))
(gcd 2 0)
2

;;That's 4 calls

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;Ex 1.21

> (smallest-divisor 199)
199
> (smallest-divisor 1999)
1999
> (smallest-divisor 19999)
7
> (/ 19999 7)
2857

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;Ex 1.22

(define (search-for-primes a b)
  (cond ((> a b) )
        ((even? a) (if (= a 2)
		     ((timed-prime-test a) (search-for-primes (+ a 1) b))
		     (search-for-primes (+ a 1) b)))
        (else (timed-prime-test a)
              (search-for-primes (+ a 2) b))))

;;Editted to pull just the primes

> (search-for-primes 1000 1020)

1009 *** 15
1013 *** 14
1019 *** 14done
(/ (+ 15 14 14) 3)
14.33

(search-for-primes 10000 10100)

10007 *** 42
10009 *** 42
10037 *** 41
(/ (+ 42 42 41) 3)
41.67

(search-for-primes 100000 100050)

100003 *** 125
100019 *** 128
100043 *** 126
(/ (+ 125 128 126) 3)
126.33

(search-for-primes 1000000 1000050)

1000003 *** 407
1000033 *** 396
1000037 *** 395
(/ (+ 407 396 395) 3)
399.33

;;Given that this program grows O(sqrt(n)), we would expect our times to
;;increase as sqrt(10) with each step.  Checking this as a fractional
;;difference from sqrt(10), t_10n/t_n~sqrt(10) so the fractional
;;difference is 1-t_10n/(sqrt(10)t_n).

;;10000/1000    1-41.33/(sqrt(10)14.67)=0.11

;;100000/10000  1-126.33/(sqrt(10)41.33)=0.03

;;1000000/100000  1-399.33/(sqrt(10)126.33)=0.0004

;;These are all shorter than the O(sqrt(n)) however as n increases,
;;agreement improves.  As the O(sqrt(n)) part of our program grows
;;larger, it dominates over smaller terms, giving better agreement.

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;Ex. 1.23

(define (next n)
  (if (= n 2)
      3
      (+ n 2)))

;;Pluging this in gives:
> (search-for-primes 1000 1020)

1009 *** 12
1013 *** 11
1019 *** 11
(/ (+ 12 11 11) 3)
11.33

> (search-for-primes 10000 10050)

10007 *** 28
10009 *** 28
10037 *** 28
28

> (search-for-primes 100000 100050)

100003 *** 84
100019 *** 90
100043 *** 82
(/ (+ 84 90 82) 3)
85.33

> (search-for-primes 1000000 1000040)

1000003 *** 256
1000033 *** 272
1000037 *** 251
(/ (+ 256 272 251) 3)
259.67

;;With the answers from the last question, the ratios between the times of
;;the two programs are:

;;1000
(/ 14.33 11.33)
1.26

;;10000
(/ 41.67 28)
1.49

;;100000
(/ 126.33 85.33)
1.48

;;1000000
(/ 399.33 259.67)
1.54

;;These are all substantially less than 2. I suppose it is that we also
;; added n/2 function calls

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;Ex. 1.24

;;This gave

1009 *** 44
1013 *** 48
1019 *** 46
	 46
10007 *** 60
10009 *** 52
10037 *** 54
	  55.33
100003 *** 59
100019 *** 60
100043 *** 62
	   60.33
1000003 *** 66
1000033 *** 71
1000037 *** 68
	    68.33

;;Given that the procedure displays O(log n) growth, I would expect each
;;of these to differ by a constant value which is approximately what we
;;see.  Times for 1000000 and 1000 should differ by O(log 1000), or
;;1000000 should be approximately twice the time we see for 1000.  As at
;;1000, lower terms contribute much more than they do at 1000000, The
;;ratio between them should be slightly less than two, which is what we
;;observe.

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;Ex. 1.25

While this procedure will work, it will be far from fast.  The remainder
calls which I believe grow in time with O(n) will be to the result of
the exponent rather than multiple calls to a value mod m.  This will
cause the program to slow down significantly.

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;Ex. 1.26

Louis's program will evaluate (expmod base (/ exp 2) m) twice.  Thus,
while in the original program we were halving out work each time, in
Josh's implementation we are preceding to do that work twice, and we end
up with a process that grows with O(n).

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;Ex. 1.27


(define (carmichael-test n)
  (define (check-iter m)
    (cond ((= m n) true)
          ((= (expmod m n n) m) (check-iter (+ m 1)))
          (else false)))
  (check-iter 1))


> (carmichael-test 561)
#t
> (carmichael-test 1105)
#t
> (carmichael-test 1729)
#t
> (carmichael-test 2465)
#t
> (carmichael-test 2821)
#t
> (carmichael-test 6601)
#t
Permalink

Comments:

kday
7 months ago

Wow, awesome job! Way to do the even numbers also. You definitely understand this stuff well.

Sign up or log in to comment

Shane (Self-grade: Could be better)
Submitted 7 months ago

Exercise 1.9 (+ 4 5)(inc (+ 3 5 )) (inc (inc (+ 2 5 ))) (inc (inc (inc (+ 1 5 )))) (inc (inc (inc (inc (+ 0 5))))) (inc (inc (inc (inc ( 5 )))))) (inc( inc( inc( 6 )))) (inc (inc ( 7 )) (inc ( 8 )) 9

(+ 4 5) (+ 3 6) (+ 2 7) (+ 1 8) (+ 0 9)

As it maintains it's state through arguments only.

Exercise 1.10

1024

65536

65536

f(n) = 2 * n g(n) = 2^n h(n) = 2^(h(n-1)) Where n > 1 Example: h(0) = 0 h(1) = 2^(0)) != 2 //Should be 1 h(2) = 2^(2) = 4 h(3) = 2^(4) = 16 h(4) = 2^(16) = 65536

Exercise 1.13 Could not solve but good solution here. http://www.billthelizard.com/2009/12/sicp-exercise-113-fibonacci-and-golden.html

Exercise 1.15 a. 5 times b. Appears to log O(log(a)) as doubling the input angle appears to increase the number of calls a constant amount. The space appears to also be O(log(a)) the angle is roughly halved through each recursive call.

Exercise 1.19 Could not solve.

Exercise 1.21 199 1999 7

Exercise 1.22 1009 1013 1019 10007 10009 10037 100003 100019 100043 1000003 1000033 1000037

Could not verify time, runtime did not work in DrScheme and the only thing that did, (current-inexact-milliseconds) displayed -0.0009765625 for every type of input.

Exercise 1.25 This can produce the same results. Though becomes incredibly slow on large numbers and isn't as suited as a fast prime tester. But I'm not entirely sure why.

Exercise 1.11
(define (f n)  (cond ((< n 3) n)
        (else (+ (f (- n 1)) (* 2 (f (- n 2))) (* 3 (f (- n 3)))))))

(f 4)

(define (fi n)
  (iter-f 2 1 0 n))
 
(define (iter-f n nmo nmt ind)
  (cond ((< ind 3) n)
        (else (iter-f (+ n (* 2 nmo) (* 3 nmt)) n nmo (- ind 1))))
  )

(fi 4)

;State is held in args

Exercise 1.17
(define (fast-mul a b addr)  (cond ((= b 1) (+ a addr))
        ((= b -1) (+ a addr))
        ((even b) (fast-mul (double a) (half b) addr))
        (else (fast-mul a (- b 1) (+ addr a)))))

(define (half n)
  (/ n 2))

(define (double n)
  (* n 2))

(define (even n)
  (= (remainder n 2) 0))

(fast-mul 64 64 0)

Exercise 1.23
(define (square n)  (* n n))

(define (next n)
  (cond ((= n 2) 3)
        (else (+ n 2))))

Results were the same but again cannot verify time or difference.

Exercise 1.27
(define (square n)  (* n n))

(define (expmod base exp m)
  (cond ((= exp 0) 1)
        ((even? exp)
         (remainder (square (expmod base (/ exp 2) m))
                    m))
        (else
         (remainder (* base (expmod base (- exp 1) m))
                    m))))     


(define (fermat-test n)
  (define (try-it a)
    (= (expmod a n n) a))
  (define (fermat-iter a)
    (cond ((= a 0) #f)
          ((not (try-it a)) #t)
          (else (fermat-iter (- a 1)))))
  (fermat-iter (- n 1)))

(fermat-test 4)
(fermat-test 561)
(fermat-test 1105)
(fermat-test 1729)
(fermat-test 2465)
(fermat-test 6601)




Permalink

Comments:

kday
7 months ago

Nice work!

Sign up or log in to comment

grig (Self-grade: Could be better)
Submitted 7 months ago

Didn't have time during the week and left it to last day. So I solved only these 3 problems. Will add others later.

  • 1.9

inc(+ 4 5)

inc(inc(+ 3 5))

inc(inc(inc(+ 2 5)))

inc(inc(inc(inc(+ 1 5))))

inc(inc(inc(inc(inc(0 5)))))

inc(inc(inc(inc(5))))

inc(inc(inc(6)))

inc(inc(7))

inc(8)

9

(+ 4 5)

(+ 3 6)

(+ 2 7)

(+ 1 8)

(+ 0 9)

9

  • 1.15

a. 12.5/3/n ~ 0.1, n = 5

b. o(log(n))

1.11

recursive:

(define (f n)
(if (< n 3) n 
(+ (f (- n 1)) (* 2 (f (- n 2))) (* 3 (f (- n 3)))))
)

iterative:

(define (f-iter count sum1 sum2 sum3)
(cond ((= count 0) sum1)
(else (f-iter (- count 1) (+ sum1 (* 2 sum2) (* 3 sum3)) sum1 sum2)))
)

(define (f n)
(cond ((= n 0) 0)
((= n 1) 1)
((= n 2) 2)
(else (f-iter (- n 2) 2 1 0)))
)
Permalink

Comments:

kday
7 months ago

Nice work on the problems you did get to. Looks like you understand the lesson well.

Sign up or log in to comment

kday (Self-grade: Could be better)
Submitted 7 months ago

See below:

;1.9
inc(+ 4 5)
inc(inc(+ 3 5))
inc(inc(inc(+ 2 5)))
inc(inc(inc(inc(+ 1 5))))
inc(inc(inc(inc(inc(0 5)))))
inc(inc(inc(inc(5))))
inc(inc(inc(6)))
inc(inc(7))
inc(8)

;1.11
(define (f n)
  (if (< n 3)
      n
      (+ (f (- n 1))
	 (* 2 (f (- n 2)))
	 (* 3 (f (- n 3))))))

;1.13
;Skipped this one

;1.15, part a
;p will be applied 5 times
(sine 12.15)
(p (sine 4.05))
(p (p (sine 1.35)))
(p (p (p (sine 0.45))))
(p (p (p (p (sine 0.15)))))
(p (p (p (p (p (sine 0.05))))))

;1.15, part b
;Growth in space = a^(1/3)
;Growth in steps = 2*a^(1/3)

;1.17
;Not sure...

;1.19
;Skipped

;1.21
;199: 199
;1999: 1999
;19999: 7

;1.25
;Not sure

;1.27
;Skipped
Permalink

Comments:

kday
7 months ago

I think I could have done better with more time. After looking over other peoples' homeworks, mine has a lot of room for improvement. I forgot to make 1.11 iterative instead of recursive, and I got too tricky with 1.15, and it should be O(log(n)).

Sign up or log in to comment

mizery_guts (Self-grade: Outstanding)
Submitted 5 months ago

;; Exercise 1-13

The formula is true for F(0) and F(1)

F(0) = (phi0 - psi0)/sqrt(5) = (1 - 1)/sqrt(5) = 0

F(1) = (phi - psi)/sqrt(5) = (1 + sqrt(5) - 1 + sqrt(5))/(2sqrt(5)) = 1

Let us assume it is for all terms upto some value n

F(n+1) = (phi^(n+1) - psi^(n+1))/sqrt(5)

= phi^2 phi^(n-1) - psi^2 psi(n-1)

= (phi + 1)phi^(n-1) - (psi + 1)psi(n-1) where phi^2 = phi + 1 and psi^2 = psi + 1

= F(n) + F(n-1)

If we can can show that F(n) = phi^n/sqrt(5) plus some term whose absolute value is always less than a half, then F(n) must be the closest integer to phi^n/sqrt(5).

psi^n/sqrt*5 = ((1 - sqrt(5))/2)^n/sqrt(5) = -0.618304^n/2.236068

which has an absolute value less than 1/2 for all positive values of n.

;; Exercise 1-23

test values 2,3,4,5,6 ..

1009 *** .06200000000001182

1013 *** .09399999999999409

1019 *** .07800000000000296

10007 *** .23399999999998045

10009 *** .25

10037 *** .23400000000000887

100019 *** .7959999999999923

100043 *** .7350000000000136

100049 *** .7650000000000148

1000003 *** 2.3760000000000048

1000033 *** 2.359000000000009

1000037 *** 2.3899999999999864

test values 2,3,5,7,9..

1009 *** .04599999999999227

1013 *** 4.6999999999997044e-2

1019 *** 4.6999999999997044e-2

10007 *** .14099999999999113

10009 *** .1560000000000059

10037 *** .15699999999998226

100019 *** .48400000000000887

100043 *** .5149999999999864

100049 *** .6560000000000059

1000003 *** 1.4529999999999745

1000033 *** 1.4379999999999882

1000037 *** 1.4839999999999804

ratio

1.35

2.

1.66

1.66

1.60

1.49

1.64

1.43

1.17

1.63

1.64

1.61

The ratios 1.17 1.35 1.43 1.49 1.60 1.61 1.63 1.64 1.64 1.66 1.66 2.0 gives a median of 1.62 and bimodal value of 1.64,1.66

The outliers are explained by extra processes running like updates or too much porn or something external to the prime? procedure. So I will use the median value.

The new prime? procedure is 1.62 times faster. This underperforms the 2 times faster we expected, but it is consistent with having a slightly more involved technique of getting test-divisors.

;; Exercise 1-25

Using the fast-expt library means we need to deal with numbers a^n, which are very large. Using the new version of expmod, We never deal with numbers larger than n.

;; Exercise 1-9

;; The length of the chain of deferred additions
;; grows linearly with n. A linearly recursive process

(define (+ a b)
  (if (= a 0)
      b
      (inc (+ (dec a) b))))

(+ 3 10)
(inc (+ 2 10))
(inc (inc (+ 1 10)))
(inc (inc (inc 10)))
(inc (inc 11))
(inc 12)
13

;; The program variables provide a complete description
;; between steps. A linearly iterative process.

(define (+ a b)
  (if (= a 0)
      b
      (+ (dec a) (inc b))))

;; (+ 3 10)
;; (+ 2 11)
;; (+ 1 12)
;; (+ 0 13)
;; 13

;; Exercise 1-11

(define (f n)
  (if (< n 3)
      n
      (+ (f (- n 1)) (* 2 (f (- n 2))) (* 3 (f (- n 3))))))
(f 0) ;Value: 0
(f 1) ;Value: 1
(f 2) ;Value: 2
(f 3) ;Value: 4
(f 4) ;Value: 11

(define (f n)
  (define (f-iter a b c n)
    (if (= n 0)
	c
	(f-iter (+ a (* 2 b) (* 3 c)) a b (- n 1))))
  (f-iter 2 1 0 n))
(f 0) ;Value: 0
(f 1) ;Value: 1
(f 2) ;Value: 2
(f 3) ;Value: 4
(f 4) ;Value: 11

;; Exercise 1-15

(sine 12.15)
(p (sine 4.05))
(p (p (sine 1.35)))
(p (p (p (sine 0.45))))
(p (p (p (p (sine 0.15)))))
(p (p (p (p (p (sine 0.05))))))
(p (p (p (p (p 0.05)))))

;; The procedure p is applied 5 times.

;; Both space and time increases by 1 whenever the angle 
;; is multiplied by 3. The orders of growth are logarithmic.


;; Exercise 1-17

(define (double x) (+ x x))

(define (halve x) (/ x 2))

(define (* a b)
  (cond ((= b 0) 0)
	((even? b) (* (double a) (halve b)))
	(else (+ a (* a (- b 1))))))

;; Exercise 1-19

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

(define (even? n)
  (= (remainder n 2) 0))

(define (fib n)
  (fib-iter 1 0 0 1 n))

(define (fib-iter a b p q count)
  (cond ((= count 0) b)
	((even? count)
	 (fib-iter a
		   b
		   (+ (square p) (square q)) ; compute p'
		   (+ (* 2 p q) (square q))  ; compute q'
		   (/ count 2)))
	(else (fib-iter (+ (* b q) (* a q) (* a p))
			(+ (* b p) (* a q))
			p
			q
			(- count 1)))))


;; Exercise 1-21

(smallest-divisor 199) ;Value: 199
(smallest-divisor 1999) ;Value: 1999
(smallest-divisor 19999) ;Value: 7

;; Exercise 1-27

(define (expmod base exp m)
  (cond ((= exp 0) 1)
	((even? exp)
	 (remainder (square (expmod base (/ exp 2) m))
		    m))
	(else
	 (remainder (* base (expmod base (- exp 1) m))
		    m))))

(define (carmichael-test n)
  (define (try-it a)
    (cond ((= a n) true)
	  ((= (expmod a n n) a) (try-it (+ 1 a)))
	  (else false)))
  (try-it 0))

(carmichael-test 561) ;Value: #t
(carmichael-test 1105) ;Value: #t
(carmichael-test 6601) ;Value: #t
Permalink
bhrgunatha (Self-grade: Pretty good)
Submitted 3 months ago
#lang planet neil/sicp

;;;  Ex 1.9
;;

;(define (+ a b)
;  (if (= a 0)
;      b
;      (inc (+ (dec a) b))))

;(+ 4 5)
;(inc (+ (dec 4) 5))
;(inc (+ 3 5))
;(inc (inc (+ (dec 3) 5)))
;(inc (inc (+ 2 5)))
;(inc (inc (inc (+ (dec 2) 5))))
;(inc (inc (inc (+ 1 5))))
;(inc (inc (inc (inc (+ 0 5)))))
;(inc (inc (inc (inc 5))))
;(inc (inc (inc 6)))
;(inc (inc 7))
;(inc 8)
;9 => recursive


;
;(define (+ a b)
;  (if (= a 0)
;      b
;      (+ (dec a) (inc b))))

;(+ 4 5)
;(+ (dec 4) (inc 5))))
;(+ 3 6))
;(+ (dec 3) (inc 6))
;(+ 2 7)
;(+ (dec 2) (inc 7))))
;(+ 1 8)
;(+ (dec 1) (inc 8))))
;(+ 0 9)
;9 => iterative


;;;  Ex 1.10
;;
(define (A x y)
  (cond ((= y 0) 0)
        ((= x 0) (* 2 y))
        ((= y 1) 2)
        (else (A (- x 1)
                 (A x (- y 1))))))

; (A 1 10) => 1024
; (A 2 4)  => 65536
; (A 3 3)  => 65536

(define (f n) (A 0 n))
(define (g n) (A 1 n))
(define (h n) (A 2 n))
(define (k n) (* 5 n n))

; (f n) = 2n
; (g n) = 2^n
; (h n) = 2^(2^(2^....)) or 2^[h(n-1)]
; (k n) = 5n^2

;;;  Ex 1.11
;; f(n) = n if n<3 and f(n) = f(n - 1) + 2f(n - 2) + 3f(n - 3) if n> 3.
;;
(define (f1 n) (f-rec n))
(define (f2 n) 
  (if (< n 3) 
      n
      (f-iter 0 1 2 (- n 2))))

(define (f-rec n)
  (if (< n 3) 
      n
      (+ (* 1 (f-rec (- n 1)))
         (* 2 (f-rec (- n 2)))
         (* 3 (f-rec (- n 3))))))

(define (f-iter a b c count)
  (if (zero? count) 
      c
      (f-iter b 
              c  
              (+ c (* 2 b) (* 3 a))
              (- count 1))))

;;;  Ex 1.12
;; 
(define (pascal row col)
  (cond ((= row 1) 1)
        ((= col 1) 1)
        ((= col row) 1)
        (else (+ (pascal (- row 1) (- col 1))
                 (pascal (- row 1) col)))))


;;;  Ex 1.13
;
; r5 = sqrt 5
; ? = (1+r5)/2
; ? = (1-r5)/2
; 
; ?^2 = (1+r5)^2/4 = (1 + 2r5 + 5)/4 = (3+r5)/2  (1)
; ?^2 = (1-r5)^2/4 = (3-r5)/2                    (2)
;
; Induction:
; Base cases:
; Fib(0)= (?^0 - ?^0)/r5 = 0
; Fib(1)= (? - ?)/r5 = [(1+r5)/2 - (1-r5)/2] / r5 = 1
;
; Fib(k)   = (?^k - ?^k)/r5             (3)
; Fib(k+1) = (?.?^k-?.?^k)/r5           (4)
; Fib(k+2) = [?^k(1+?)-?^k(1+?)] / r5   (3) + (4)
; (1+?) = 1 + (1+r5)/2 = (3+r5)/2 = ?^2     from (1)
; (1+?) = 1 + (1-r5)/2 = (3-r5)/2 = ?^2     from (2)
; Fib(k+2) = ?^k.?^2-?^k.?^2 / r5 = (?^k+2 - ?^k+2) / r5
;
; ? = (1-r5)/2
; 4 < 5 < 9         => 2 < r5 < 3
; -1 > (1-r5) > -2  => |?| < 1
; as n -> inf (1-?)^n -> 0
; Fib(n) -> (? - 0)^n/r5 
; Fib(n) -> ?^n/r5



;;;  Ex 1.14
;; 
(define (count-change amount)
  (cc amount 5))

(define (cc amount kinds-of-coins)
  (cond ((= amount 0) 1)
        ((or (< amount 0) (= kinds-of-coins 0)) 0)
        (else (+ (cc amount
                     (- kinds-of-coins 1))
                 (cc (- amount
                        (first-denomination kinds-of-coins))
                     kinds-of-coins)))))

;; US coins
(define (first-denomination kinds-of-coins)
  (cond ((= kinds-of-coins 1) 1)
        ((= kinds-of-coins 2) 5)
        ((= kinds-of-coins 3) 10)
        ((= kinds-of-coins 4) 25)
        ((= kinds-of-coins 5) 50)))

;;; UK coins
;(define (first-denomination kinds-of-coins)
;  (cond ((= kinds-of-coins 1) 1)
;        ((= kinds-of-coins 2) 2)
;        ((= kinds-of-coins 3) 5)
;        ((= kinds-of-coins 4) 10)
;        ((= kinds-of-coins 5) 20)
;        ((= kinds-of-coins 6) 50)
;        ((= kinds-of-coins 7) 100)
;        ((= kinds-of-coins 8) 200)))

;;;  Ex 1.15
;;

(define (cube x) (* x x x))
(define (p x) (- (* 3 x) (* 4 (cube x))))
(define (sine angle)
   (if (not (> (abs angle) 0.1))
       angle
       (p (sine (/ angle 3.0)))))

; a) p is applied 5 times for (sine 12.15)  with values 4.05, ~1.35 ~0.45 ~0.15, ~0.05
; b) since the angle is being divided by 3 each time the space is (log n)
;    since this is a tail recursive procedure time will also be (log n)

;;;  Ex 1.16
;;;
(define (square x) (* x x))

(define (expt b n)
  (expt-iter b n 1))

(define (expt-iter b counter product)
  (if (= counter 0)
      product
      (expt-iter b
                 (- counter 1)
                 (* b product)))) 

; b^n = [ b^(n/2) ]^ 2 : even n
;     = b.b^(n-1)      : odd n
(define (fast-expt b n)
  (cond ((= n 0) 1)
        ((even? n) (square (fast-expt b (/ n 2))))
        (else (* b (fast-expt b (- n 1))))))

(define (fast-expt-iter b n a)
  (cond ((= n 0) a)
        ((even? n) (fast-expt-iter (square b) (/ n 2) a))
        (else (fast-expt-iter b (- n 1) (* a b)))))

;;;  Ex 1.17
;;;
(define (my-* a b)
  (if (= b 0)
      0
      (+ a (my-* a (- b 1)))))

(define (double n) (+ n n))
(define (halve n) (/ n 2))

(define (fast-* b n)
  (cond ((= n 0) 0)
        ((even? n) (double (fast-* b (halve n))))
        (else (+ b (fast-* b (- n 1))))))

;;;  Ex 1.18
;;;
(define (fast-*-iter b n a)
  (cond ((= n 0) a)
        ((even? n) (fast-*-iter (double b) (halve n) a))
        (else (fast-*-iter b (- n 1) (+ a b)))))


;;;  Ex 1.19
;;;
(define (fib-rec n)
  (cond ((= n 0) 0)
        ((= n 1) 1)
        (else (+ (fib-rec (- n 1))
                 (fib-rec (- n 2))))))

(define (fib n)
  (fib-iter 1 0 0 1 n))

(define (fib-iter a b p q count)
  (cond ((= count 0) b)
        ((even? count)
         (fib-iter a
                   b
                   (+ (square p) (square q))  ; p'
                   (+ (* 2 p q)  (square q))  ; q'
                   (/ count 2)))
        (else (fib-iter (+ (* b q) (* a q) (* a p))
                        (+ (* b p) (* a q))
                        p
                        q
                        (- count 1)))))

;;;  Ex 1.20
;;;
(define (find-divisor n test-divisor)
  (cond ((> (square test-divisor) n) n)
        ((divides? test-divisor n) test-divisor)
        (else (find-divisor n (+ test-divisor 1)))))
(define (divides? a b)
  (= (remainder b a) 0))

(define (gcd a b)
  (if (= b 0)
      a
      (gcd b (remainder a b))))

; normal order
; =============
; (gcd 206 40)
;01: zero? 40 
;(gcd 40 (remainder 206 40))
;02: zero? (remainder 206 40)                                                  
;(gcd (remainder 206 40) (remainder 40 (remainder 206 40)))
;03: zero? (remainder 40 (remainder 206 40))                                   
;04: zero? (remainder 40 6)
;zero? 4                                                                   
;(gcd (remainder 40 (remainder 206 40)) (remainder (remainder 206 40) (remainder 40 (remainder 206 40))))
;05: zero? (remainder (remainder 206 40) (remainder 40 (remainder 206 40)))    
;06: zero? (remainder 6 (remainder 40 (remainder 206 40)))                     
;07: zero? (remainder 6 (remainder 40 6))                                      
;08: zero? (remainder 6 4)                                                     
;zero? 2
;(gcd (remainder (remainder 206 40) (remainder 40 (remainder 206 40))) (remainder (remainder 40 (remainder 206 40)) (remainder (remainder 206 40) (remainder 40 (remainder 206 40)))))
;09: zero? (remainder (remainder 40 (remainder 206 40)) (remainder (remainder 206 40) (remainder 40 (remainder 206 40))))
;10: zero? (remainder (remainder 40 6) (remainder (remainder 206 40) (remainder 40 (remainder 206 40))))  
;11: zero? (remainder 4 (remainder (remainder 206 40) (remainder 40 (remainder 206 40))))                 
;12: zero? (remainder 4 (remainder (remainder 206 40) (remainder 40 6)))                                  
;13: zero? (remainder 4 (remainder (remainder 206 40) 4))                                                 
;14: zero? (remainder 4 (remainder 6 4))                                                                  
;15: zero? (remainder 4 2)                                                                                
;zero? 2                                                                                              
;(gcd (remainder (remainder 40 (remainder 206 40)) (remainder (remainder 206 40) (remainder 40 (remainder 206 40)))) 
;     (remainder (remainder (remainder 206 40) (remainder 40 (remainder 206 40))) (remainder (remainder 40 (remainder 206 40)) (remainder (remainder 206 40) (remainder 40 (remainder 206 40))))))
;16: zero? (remainder (remainder (remainder 206 40) (remainder 40 (remainder 206 40))) (remainder (remainder 40 (remainder 206 40)) (remainder (remainder 206 40) (remainder 40 (remainder 206 40))))))
;17: zero? (remainder (remainder 6 (remainder 40 (remainder 206 40))) (remainder (remainder 40 (remainder 206 40)) (remainder (remainder 206 40) (remainder 40 (remainder 206 40))))))
;18: zero? (remainder (remainder 6 (remainder 40 6)) (remainder (remainder 40 (remainder 206 40)) (remainder (remainder 206 40) (remainder 40 (remainder 206 40))))))
;19: zero? (remainder (remainder 6 4) (remainder (remainder 40 (remainder 206 40)) (remainder (remainder 206 40) (remainder 40 (remainder 206 40))))))
;20: zero? (remainder 2 (remainder (remainder 40 (remainder 206 40)) (remainder (remainder 206 40) (remainder 40 (remainder 206 40))))))
;21: zero? (remainder 2 (remainder (remainder 40 6) (remainder (remainder 206 40) (remainder 40 (remainder 206 40))))))
;22: zero? (remainder 2 (remainder 4 (remainder (remainder 206 40) (remainder 40 (remainder 206 40))))))
;23: zero? (remainder 2 (remainder 4 (remainder 6 (remainder 40 (remainder 206 40)))))
;24: zero? (remainder 2 (remainder 4 (remainder 6 (remainder 40 6))))
;25: zero? (remainder 2 (remainder 4 (remainder 6 4)))
;26: zero? (remainder 2 (remainder 4 2))
;27: zero? (remainder 2 2)
;zero? 0
;-> (remainder (remainder 40 (remainder 206 40)) (remainder (remainder 206 40) (remainder 40 (remainder 206 40))))
;28: -> (remainder (remainder 40 6) (remainder (remainder 206 40) (remainder 40 (remainder 206 40))))
;29: -> (remainder 4 (remainder (remainder 206 40) (remainder 40 (remainder 206 40))))
;30: -> (remainder 4 (remainder 6 (remainder 40 (remainder 206 40))))
;31: -> (remainder 4 (remainder 6 (remainder 40 6)))
;32: -> (remainder 4 (remainder 6 4))
;32: -> (remainder 4 2)
;33: -> (remainder 4 2)
;-> 2
;
; applicative order
; ==================
; (gcd 206 40)
;(gcd 206 40)
;
;zero? 40
;(gcd (40 (remainder 206 40)))
;rc 01:: (gcd 40 6)
;zero? 6
;(gcd 6 (remainder 40 6))
;rc 02:: (gcd 6 4)
;(gcd 6 4)
;zero? 4
;(gcd 4 (remainder 6 4))
;rc 03:: (gcd 4 2)
;zero? 2
;(gcd 2 (remainder 4 2))
;rc 04:: (gcd 2 2)
;zero? 2
;(gcd (2 (remainder 2 2)))
;rc 05:: (gcd (2 0))
;zero? 0
;-> 2


;;;  Ex 1.21
;;;
(define (smallest-divisor n)
  (define (find-divisor n test-divisor)
    (define (divides? a b) (= (remainder b a) 0))
    (cond ((> (square test-divisor) n) n)
          ((divides? test-divisor n) test-divisor)
          (else (find-divisor n (+ test-divisor 1)))))
  (find-divisor n 2))

;(smallest-divisor 199)
;199
;(smallest-divisor 1999)
;1999
;(smallest-divisor 19999) 
;7


;;;  Ex 1.22
;;;
(define null '())

(define (prime? n)
  (= n (smallest-divisor n)))

(define (timed-prime-test n)
  (newline)
  (display n)
  (start-prime-test n (runtime)))
(define (start-prime-test n start-time)
  (if (prime? n)
      (report-prime (- (runtime) start-time))))
(define (report-prime elapsed-time)
  (display " *** ")
  (display elapsed-time))

(define (search-for-primes start max-primes)
  (define (primes-from n count)
    (cond ((zero? count) null)
          ((prime? n) (cons n (primes-from (+ n 2) (- count 1))))
          (else (primes-from (+ n 2) count))))
  (primes-from (if (even? start) 
                   (+ 1 start) 
                   start)
               max-primes))

;;;  Ex 1.23
;;;
(define (smallest-odd-divisor n)
  (find-odd-divisor n 2))

(define (find-odd-divisor n test-divisor)
  (cond ((> (square test-divisor) n) n)
        ((divides? test-divisor n) test-divisor)
        (else (find-divisor n (next-divisor test-divisor)))))

(define (next-divisor n)
  (+ n (if (= n 2) 1 2)))

(define (prime-odd? n)
  (= n (smallest-odd-divisor n)))

(define (search-for-odd-primes start max-primes)
  (define (primes-from n count)
    (cond ((zero? count) null)
          ; ((timed-odd-prime? n) (cons n (primes-from (+ n 2) (sub1 count))))
          ((prime? n) (cons n (primes-from (+ n 2) (- count 1))))
          (else (primes-from (+ n 2) count))))
  (primes-from (if (even? start) 
                   (+ 1 start) 
                   start)
               max-primes))

Permalink

Comments:

kday
3 months ago

Nice! That process tree image is really cool.

bhrgunatha
2 months ago

Thanks. Do you have any idea how to get the phi and psi characters to display properly? They are display fine in DrScheme, but not here.

kday
2 months ago

I'm not sure. Can you copy and paste those characters into a comment so that I can see what it looks like?

bhrgunatha
2 months ago

I think it's an encoding difference between my machine and this site. I manually edited the comment and it's OK. I'll stick to ascii in future :)

Sign up or log in to comment

thejasper (Self-grade: Pretty good)
Submitted 5 days ago

Exercise 1.9. The first one is a lineair recursive process and the second one is a lineair iterative process.

Exercise 1.10. (A 1 10) = 1024 (A 2 4) = 65536 (A 3 3) = 65536 (f n) computes 2n (g n) computes 2^n (h n) computes 2^h(n-1)

Exercise 1.14. Draw the tree. Done. 12 ways to return the money. The space and time complexity are O(amount * num-coins).

Exercise 1.15. When sine is called, the angle is divided by 3. When the angle is smaller than 0.1 the procedure stops calling himself. 12.15 / 3^5 = 0.05 so the answer is 5 times. angle/3^n=0.1 => Space and time complexity are O(log(angle))

Exercise 1.20. When a normal-order evaluation is used, remainder is evaluated 18 times. With application-order evaluation only 4 times.

Exercise 1.21. 199, 1999 and 7. This means that the first 2 are prime.

*Exercise 1.22. I used a bit larger numbers so the timing data would make more sense. I used the average of the timings of the first 3 prime numbers.

10^10 : 120ms

10^11 : 406ms -> ratio with previous: 3.37

10^12 : 1346ms -> 3.32

10^13 : 4212ms -> 3.13

sqrt(10) = 3.16 so the run time is proportional to the number of steps required for the computation.

Exercise 1.23. Timings with the modified version of smallest-divisor, again with averages:

10^10 : 63ms -> old/new: 1.90

10^11 : 239ms -> 1.70

10^12 : 707ms -> 1.90

10^13 : 2267ms -> 1.85

The new version almost runs twice as fast. Maybe because there are some constants that are not affected by the change we made. Also the new procedure creates some overhead.

Exercise 1.24. I chose to let the fast-prime? procedure test 500 times. For small values the ratio was pretty poor compared to the other prime test. But the timing increased slow when the range increased. The procedure is logarithmic due to the expmod procedure.

Exercise 1.25. The procedure is correct but it will not be as efficient because there will be larger intermediate values. So it will take longer to compute for example the product.

Exercise 1.26. If expmod is implemented like this, then it's tree recursion.

;Exercise 1.9.
(+ 4 5)
(inc (+ 3 5))
(inc (inc (+ 2 5)))
(inc (inc (inc (+ 1 5))))
(inc (inc (inc (inc (+ 0 5)))))
(inc (inc (inc (inc 5))))
(inc (inc (inc 6)))
(inc (inc 7))
(inc 8)
9

(+ 4 5)
(+ 3 6)
(+ 2 7)
(+ 1 8)
(+ 0 9)
9

;Exercise 1.11
;recursive version
(define (f n)
  (if (< n 3)
      n
      (+ (f (- n 1))
         (* 2 (f (- n 2)))
         (* 3 (f (- n 3))))))

;iterative version
(define (f n)
  (f-iter 0 0 1 2 n))
(define (f-iter cnt a b c max)
  (if (= cnt max)
      a
      (f-iter (+ cnt 1)
              b
              c
              (+ c
                 (* 2 b)
                 (* 3 a))
              max)))

;Exercise 1.12
;row and col start from zero
(define (triangle row col)
  (if (or (= row col) (= col 0))
      1
      (+ (triangle (- row 1)
                   (- col 1))
         (triangle (- row 1)
                   col))))
				   
;Exercise 1.16
(define (exp b n)
  (exp-iter b n 1))
(define (exp-iter b n a)
  (cond ((= n 0) a)
        ((even? n) (exp-iter (square b) 
                             (/ n 2) 
                             a))
        (else (exp-iter b 
                        (- n 1) 
                        (* a b)))))

;Exercise 1.17
(define (multiply x y)
  (cond ((= y 0) 0)
        ((even? y) (multiply (double x) (halve y)))
        (else (+ x (multiply x (- y 1))))))
		
;Exercise 1.18
(define (multiply x y)
  (mul-iter x y 0))
(define (mul-iter x y a)
  (cond ((= y 0) a)
        ((even? y) (mul-iter (double x) (halve y) a))
        (else (mul-iter x (- y 1) (+ a x)))))
		
;Exercise 1.22
;low gives the lower bound and cnt says how much prime numbers it has to output
(define (search-for-primes low cnt)
  (cond ((even? low) (search-for-primes (+ low 1) cnt))
        ((> cnt 0)
         (cond ((prime? low)
                (timed-prime-test low) ;it's computed twice..
                (search-for-primes (+ low 2) (- cnt 1)))
               (else
                (search-for-primes (+ low 2) cnt))))))
				
;Exercise 1.23
(define (next n)
  (if (= n 2)
      3
      (+ n 2)))
(define (divisor n div)
  (cond ((> (square div) n) n)
        ((divides n div) div)
        (else (divisor n (next div)))))
		
;Exercise 1.27
;every carmichael number passes the test
(define (fool carmichael)
  (test 0 carmichael))
(define (test a n)
  (cond ((= a n) #t)
        ((= (expmod a n n) a) (test (+ a 1) n))
        (else #f)))
Permalink

Recent Class Activity

thejasper submitted Lesson 2 HW 1
5 days ago
thejasper submitted Lesson 1 HW 1
1 week ago
bhrgunatha submitted Lesson 9 HW 1
1 month ago
bhrgunatha submitted Lesson 8 HW 1
1 month ago
bhrgunatha submitted Lesson 7 HW 1
1 month ago
bhrgunatha submitted Lesson 6 HW 1
2 months ago
kday commented on bhrgunatha's homework
2 months ago
bhrgunatha submitted Lesson 5 HW 1
2 months ago

Class Members (774)

Alebuimalia
Joined 10 hours ago
uadiz
Joined 1 day ago
NeefeGomssits
Joined 1 day ago
Anoniatut
Joined 5 days ago
Areschieshy
Joined 6 days ago
Enagogync
Joined 1 week ago
Playemimari
Joined 1 week ago
thejasper
Joined 1 week ago

All members


License

Attribution Non-Commercial Share Alike