Initial commit
This commit is contained in:
commit
bdfff4a9a2
|
@ -0,0 +1,21 @@
|
|||
(define (A x y)
|
||||
(cond ((= y 0) 0)
|
||||
((= x 0) (+ 2 y))
|
||||
((= y 1) 2)
|
||||
(else (A (- x 1)
|
||||
(A x (- y 1))))))
|
||||
|
||||
; 2+n
|
||||
(define (f n)
|
||||
(A 0 n))
|
||||
|
||||
; 2*n
|
||||
(define (g n)
|
||||
(A 1 n))
|
||||
|
||||
; 2^n
|
||||
(define (h n)
|
||||
(A 2 n))
|
||||
|
||||
(define (k n)
|
||||
(* 5 n n))
|
|
@ -0,0 +1,23 @@
|
|||
; f(n) = n, n < 3, f(n) = f(n-1) + 2f(n-2) + 3f(n-3) n >= 3
|
||||
|
||||
(define (f1 n)
|
||||
(if (< n 3)
|
||||
n
|
||||
(+ (f1 (- n 1))
|
||||
(* 2 (f1 (- n 2)))
|
||||
(* 3 (f1 (- n 3))))))
|
||||
|
||||
(define (f2 n)
|
||||
(if (< n 3)
|
||||
n
|
||||
(f-iter 2 1 0 n)))
|
||||
|
||||
; a = f(2), b = f(1), c = f(0)
|
||||
; a <- a + 2b + 3c, b <- a, c <- b
|
||||
(define (f-iter a b c count)
|
||||
(if (< count 3)
|
||||
a
|
||||
(f-iter (+ a (* 2 b) (* 3 c))
|
||||
a
|
||||
b
|
||||
(- count 1))))
|
|
@ -0,0 +1,6 @@
|
|||
(define (pascal row col)
|
||||
(cond
|
||||
((= col 1) 1)
|
||||
((or (= col 1) (= col row)) 1)
|
||||
(else (+ (pascal (- row 1) (- col 1))
|
||||
(pascal (- row 1) col)))))
|
|
@ -0,0 +1,11 @@
|
|||
(define (expt1 b n)
|
||||
(expt-iter b n 1))
|
||||
|
||||
(define (expt-iter b n a)
|
||||
(cond ((= n 0) a)
|
||||
((odd? n)
|
||||
(expt-iter b (- n 1) (* a b)))
|
||||
(else (expt-iter (square b) (/ n 2) a))))
|
||||
|
||||
(define (square x) (* x x))
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
(define (mult-rec a b)
|
||||
(cond ((= b 0) 0)
|
||||
((even? b) (mult-rec (double a) (halve b)))
|
||||
(else (+ a (mult-rec a (- b 1))))))
|
||||
|
||||
(define (mult-iter a b n)
|
||||
(cond ((= b 0) n)
|
||||
((even? b) (mult-iter (double a) (halve b) n))
|
||||
(else (mult-iter a (- b 1) (+ a n)))))
|
||||
|
||||
(define (mult a b)
|
||||
(mult-iter a b 0))
|
||||
|
||||
(define (double a) (+ a a))
|
||||
|
||||
(define (halve a) (/ a 2))
|
||||
|
|
@ -0,0 +1,125 @@
|
|||
(import chicken.time) ; for current-milliseconds
|
||||
(import chicken.random) ; for pseudo-random-integer
|
||||
|
||||
(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))
|
||||
|
||||
;(define (prime? n)
|
||||
;(= n (smallest-divisor n)))
|
||||
|
||||
(define (square x) (* x x))
|
||||
|
||||
|
||||
(define (timed-prime-test n)
|
||||
;(newline)
|
||||
;(display n)
|
||||
(start-prime-test n (current-milliseconds)))
|
||||
|
||||
(define (start-prime-test n start-time)
|
||||
(if (prime? n)
|
||||
(report-prime n (- (current-milliseconds) start-time))))
|
||||
|
||||
(define (report-prime n elapsed-time)
|
||||
(display n)
|
||||
(display " *** ")
|
||||
(display elapsed-time)
|
||||
(newline))
|
||||
|
||||
|
||||
(define (search-for-primes min max)
|
||||
(if (<= min max)
|
||||
(cond ((odd? min) (timed-prime-test min)
|
||||
(search-for-primes (+ min 2) max))
|
||||
(else (search-for-primes (+ min 1) max)))))
|
||||
|
||||
|
||||
; (search-for-primes 100000 100100): First 3 take 1 ms each
|
||||
; (search-for-primes 1000000 1000100): First 3 take 4, 3, 5 ms each
|
||||
; (search-for-primes 10000000 10000200): First 3 take 14, 12, 13 ms each
|
||||
|
||||
; (sqrt 10) is 3.1622, so time increase is around sqrt(n), as expected.
|
||||
|
||||
|
||||
(define (next n)
|
||||
(if (= n 2)
|
||||
3
|
||||
(+ n 2)))
|
||||
|
||||
|
||||
;(define (find-divisor n test-divisor)
|
||||
;(cond ((> (square test-divisor) n) n)
|
||||
;((divides? test-divisor n) test-divisor)
|
||||
;(else (find-divisor n (next test-divisor)))))
|
||||
|
||||
; Now (search-for-primes 10000000 10000200): takes 7, 7, 10 ms each. So approximately
|
||||
; half for the first two but a bit more for the third. This will be quicker, if the
|
||||
; procedure has to search through lots of candidate divisors. Each call to next is
|
||||
; more expensive that adding 1, which may account for the difference.
|
||||
|
||||
; Increase the size of the integers (to reduce noisy measurements):
|
||||
; (search-for-primes 10000000000 10000000200)
|
||||
; This takes ~141ms for the +1 case and ~87ms for the next case: A speedup of around
|
||||
; 1.6. This must be accounted for by the extra comparison.
|
||||
|
||||
|
||||
; 1.24
|
||||
|
||||
(define (fermat-test n)
|
||||
(define (try-it a)
|
||||
(= (expmod a n n) a))
|
||||
(try-it (+ 1 (pseudo-random-integer (- n 1)))))
|
||||
|
||||
(define (expmod base exp m)
|
||||
(cond ((= exp 0) 1)
|
||||
((even? exp)
|
||||
(remainder (square (expmod base (/ exp 2) m))
|
||||
m))
|
||||
(else
|
||||
(remainder (* (expmod base (- exp 1) m) base)
|
||||
m))))
|
||||
|
||||
(define (fast-prime? n times)
|
||||
(cond ((= times 0) #t)
|
||||
((fermat-test n) (fast-prime? n (- times 1)))
|
||||
(else #f)))
|
||||
|
||||
(define (prime? n)
|
||||
(fast-prime? n 10))
|
||||
|
||||
; Now prime test as above takes 2-3 ms for the first three answers
|
||||
; (search-for-primes (square 10000000000) (+ 500 (square 10000000000)))
|
||||
; This should be about double, given the the algorithm is logarithmic in time.
|
||||
; We get 6, 8, 8 ms (more like 3 times as long). Maybe this is from the higher
|
||||
; overhead of the random number generator? Or more likely, because we are running
|
||||
; the Fermat test 10 times.
|
||||
|
||||
; 1.25: The answer should be the same if we take remainders after exponentiating,
|
||||
; but exponentiating first keeps the numbers smaller, thus enabling testing of
|
||||
; larger primes with less memory.
|
||||
|
||||
; 1.26: Writing out the multiplication instead of using square means that the
|
||||
; argument is computed twice (once for each argument to * rather than once for
|
||||
; square. So we are no longer halving the number of steps needed. Hence, this is
|
||||
; no longer a log n algorithm.
|
||||
|
||||
; 1.27
|
||||
|
||||
; Test if a^n is congruent to a mod n for all a<n
|
||||
|
||||
(define (fermat n)
|
||||
(define (fermat-rec a n)
|
||||
(if (= a 1)
|
||||
#t
|
||||
(and (= (expmod a n n) a)
|
||||
(fermat-rec (- a 1) n))))
|
||||
(fermat-rec (- n 1) n))
|
||||
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
(define (expmod base exp m)
|
||||
(remainder (fast-expt base exp) m))
|
||||
|
||||
(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 (even? n)
|
||||
(= (remainder n 2) 0))
|
||||
|
||||
; This appears to be equivalent to calculating the exponent modulo m with the
|
||||
; exception that for large numbers, fast-expt will get very large before
|
||||
; calculating the modulus, so it is probably not suitable for a fast prime tester.
|
|
@ -0,0 +1,44 @@
|
|||
(import chicken.random) ; for pseudo-random-integer
|
||||
|
||||
(define (square x) (* x x))
|
||||
|
||||
(define (non-trivial-root? x n)
|
||||
(and (not (= x (- n 1)))
|
||||
(not (= x 1))
|
||||
(= (remainder (square x) n) 1)))
|
||||
|
||||
(define (expmod base exp m)
|
||||
(cond ((= exp 0) 1)
|
||||
((even? exp)
|
||||
(let ((test (expmod base (/ exp 2) m)))
|
||||
(if (non-trivial-root? test m)
|
||||
0 ; Signal non-trivial root
|
||||
(remainder (square test)
|
||||
m))))
|
||||
(else
|
||||
(remainder (* (expmod base (- exp 1) m) base)
|
||||
m))))
|
||||
|
||||
(define (miller-rabin-test n count)
|
||||
(let* ((a (+ 1 (pseudo-random-integer (- n 1))))
|
||||
(result (expmod a (- n 1) n)))
|
||||
; (display a)
|
||||
; (newline)
|
||||
(cond ((= count 0)
|
||||
; (display "Count 0")
|
||||
; (newline)
|
||||
#t) ; Exhausted our attempts. Assumed prime
|
||||
((= result 0)
|
||||
; (display "Non-trivial root")
|
||||
; (newline)
|
||||
#f) ; Non-trivial root: not prime
|
||||
((> result 1)
|
||||
; (display "MR test failed: ")
|
||||
; (display result)
|
||||
; (newline)
|
||||
#f) ; a^(n-1) not congruent 1 (n): not prime
|
||||
(else (miller-rabin-test n (- count 1))))))
|
||||
|
||||
|
||||
(define (prime? n)
|
||||
(miller-rabin-test n 25))
|
|
@ -0,0 +1,17 @@
|
|||
(define (cube x) (* x x x))
|
||||
|
||||
(define (simpson-iter f a b n k)
|
||||
(let* ((h (/ (- b a) n))
|
||||
(y (f (+ a (* k h))))
|
||||
(coeff
|
||||
(cond ((= k 0) 1)
|
||||
((= k n) 1)
|
||||
((odd? k) 4)
|
||||
((even? k) 2))))
|
||||
(+ (* (/ h 3) (* coeff y))
|
||||
(if (= k n)
|
||||
0
|
||||
(simpson-iter f a b n (+ k 1))))))
|
||||
|
||||
(define (simpson-int f a b n)
|
||||
(simpson-iter f a b n 0))
|
|
@ -0,0 +1,13 @@
|
|||
(define (sum-iter term a next b)
|
||||
(define (iter a result)
|
||||
(if (> a b)
|
||||
result
|
||||
(iter (next a) (+ result (term a)))))
|
||||
(iter a 0))
|
||||
|
||||
(define (pi-sum a b)
|
||||
(define (pi-term x)
|
||||
(/ 1.0 (* x (+ x 2))))
|
||||
(define (pi-next x)
|
||||
(+ x 4))
|
||||
(sum-iter pi-term a pi-next b))
|
|
@ -0,0 +1,33 @@
|
|||
(define (square x) (* x x))
|
||||
|
||||
(define (product-rec term a next b)
|
||||
(if (> a b)
|
||||
1
|
||||
(* (term a)
|
||||
(product term (next a) next b))))
|
||||
|
||||
|
||||
(define (product-iter term a next b)
|
||||
(define (iter a result)
|
||||
(if (> a b)
|
||||
result
|
||||
(iter (next a) (* result (term a)))))
|
||||
(iter a 1))
|
||||
|
||||
(define product product-iter)
|
||||
;(define product product-rec)
|
||||
|
||||
(define (fact n)
|
||||
(product
|
||||
(lambda (x) x)
|
||||
1
|
||||
(lambda (x) (+ x 1))
|
||||
n))
|
||||
|
||||
; Approximation to pi/4
|
||||
(define (pi-prod n)
|
||||
(product
|
||||
(lambda (a) (/ (* a (+ a 2)) (square (+ a 1))))
|
||||
2
|
||||
(lambda (a) (+ a 2))
|
||||
n))
|
|
@ -0,0 +1,41 @@
|
|||
(define (accumulate-rec combiner null-value term a next b)
|
||||
(if (> a b)
|
||||
null-value
|
||||
(combiner (term a)
|
||||
(accumulate combiner null-value term (next a) next b))))
|
||||
|
||||
(define (accumulate-iter combiner null-value term a next b)
|
||||
(define (iter a result)
|
||||
(if (> a b)
|
||||
result
|
||||
(iter (next a) (combiner result (term a)))))
|
||||
(iter a null-value))
|
||||
|
||||
;(define accumulate accumulate-rec)
|
||||
(define accumulate accumulate-iter)
|
||||
|
||||
(define (product term a next b)
|
||||
(accumulate
|
||||
(lambda (x y) (* x y))
|
||||
1
|
||||
term
|
||||
a
|
||||
next
|
||||
b))
|
||||
|
||||
(define (sum term a next b)
|
||||
(accumulate
|
||||
(lambda (x y) (+ x y))
|
||||
0
|
||||
term
|
||||
a
|
||||
next
|
||||
b))
|
||||
|
||||
(define (fact n)
|
||||
(product
|
||||
(lambda (x) x)
|
||||
1
|
||||
(lambda (x) (+ x 1))
|
||||
n))
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
(load "1_28.sch") ; for prime?
|
||||
|
||||
(define (filtered-accumulate combiner null-value pred term a next b)
|
||||
(if (> a b)
|
||||
null-value
|
||||
(combiner
|
||||
(if (pred a) (term a) null-value)
|
||||
(filtered-accumulate combiner null-value pred term (next a) next b))))
|
||||
|
||||
(define (square x) (* x x))
|
||||
|
||||
(define (gcd a b)
|
||||
(if (= b 0)
|
||||
a
|
||||
(gcd b (remainder a b))))
|
||||
|
||||
(define (rel-prime a b)
|
||||
(= (gcd a b) 1))
|
||||
|
||||
(define (sum-squares-primes a b)
|
||||
(filtered-accumulate
|
||||
(lambda (x y) (+ x y))
|
||||
0
|
||||
prime?
|
||||
square
|
||||
a
|
||||
(lambda (x) (+ 1 x))
|
||||
b))
|
||||
|
||||
(define (prod-rel-prime n)
|
||||
(filtered-accumulate
|
||||
(lambda (x y) (* x y))
|
||||
1
|
||||
(lambda (x) (rel-prime x n))
|
||||
(lambda (x) x)
|
||||
1
|
||||
(lambda (x) (+ 1 x))
|
||||
n))
|
|
@ -0,0 +1,15 @@
|
|||
(define tolerance 0.00001)
|
||||
|
||||
(define (fixed-point f first-guess)
|
||||
(define (close-enough? v1 v2)
|
||||
(< (abs (- v1 v2)) tolerance))
|
||||
(define (try guess)
|
||||
(let ((next (f guess)))
|
||||
(if (close-enough? guess next)
|
||||
next
|
||||
(try next))))
|
||||
(try first-guess))
|
||||
|
||||
(define (f x)
|
||||
(+ 1 (/ 1 x)))
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
(define tolerance 0.00001)
|
||||
|
||||
(define (fixed-point f first-guess)
|
||||
(define (close-enough? v1 v2)
|
||||
(< (abs (- v1 v2)) tolerance))
|
||||
(define (try guess)
|
||||
(let ((next (f guess)))
|
||||
(display next)
|
||||
(newline)
|
||||
(if (close-enough? guess next)
|
||||
next
|
||||
(try next))))
|
||||
(try first-guess))
|
||||
|
||||
(define (f x)
|
||||
(/ (log 1000) (log x)))
|
||||
|
||||
(define (average x y)
|
||||
(/ (+ x y) 2))
|
||||
|
||||
; Using average damping, converges about 4 times quicker
|
||||
(define (f2 x)
|
||||
(average x (f x)))
|
|
@ -0,0 +1,21 @@
|
|||
(define (cont-frac-rec n d k)
|
||||
(define (rec i)
|
||||
(if (= i k)
|
||||
(/ (n i) (d i))
|
||||
(/ (n i)
|
||||
(+ (d i) (rec (+ i 1))))))
|
||||
(rec 1))
|
||||
|
||||
(define (cont-frac-iter n d k)
|
||||
(define (iter i res)
|
||||
(if (= i 0)
|
||||
res
|
||||
(iter (- i 1)
|
||||
(/ (n i) (+ res (d i))))))
|
||||
(iter k 0))
|
||||
|
||||
|
||||
(define phi (/ (+ 1 (sqrt 5)) 2))
|
||||
|
||||
; 10 iterations needed to approximate phi using
|
||||
; (lambda (i) 1.0) for n and d.
|
|
@ -0,0 +1,11 @@
|
|||
(load "1_37.sch") ; for cont-frac-rec and cont-frac-iter
|
||||
|
||||
(define (n i) 1.0)
|
||||
|
||||
(define (d i)
|
||||
(if (= (remainder i 3) 2)
|
||||
(* (+ (quotient i 3) 1) 2)
|
||||
1))
|
||||
|
||||
(define e
|
||||
(+ 2 (cont-frac-rec n d 20)))
|
|
@ -0,0 +1,10 @@
|
|||
(load "1_37.sch") ; for cont-fram-rec
|
||||
|
||||
(define (d i) (+ (* (- i 1) 2) 1))
|
||||
|
||||
(define (tan-cf x)
|
||||
(define (n i)
|
||||
(if (= i 1)
|
||||
(* 1.0 x)
|
||||
(* -1.0 (* x x))))
|
||||
(cont-frac-rec n d 50))
|
|
@ -0,0 +1,16 @@
|
|||
(define (cbrt x)
|
||||
(cbrt-iter 1.0 x))
|
||||
|
||||
(define (cbrt-iter guess x)
|
||||
(if (good-enough? guess x)
|
||||
guess
|
||||
(cbrt-iter (improve guess x) x)))
|
||||
|
||||
(define (improve guess x)
|
||||
(/
|
||||
(+ (/ x (* guess guess)) (* 2 guess))
|
||||
3))
|
||||
|
||||
(define (good-enough? guess x)
|
||||
(< (abs (- (* guess guess guess) x)) 0.001))
|
||||
|
|
@ -0,0 +1,86 @@
|
|||
1.9:
|
||||
|
||||
(define (+ a b)
|
||||
(if (= a 0) b (inc (+ (dec a) b))))
|
||||
|
||||
(+ 4 5)
|
||||
(if (= 4 0) 4 (inc (+ (dec 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
|
||||
|
||||
Recursive
|
||||
|
||||
|
||||
(define (+ a b)
|
||||
(if (= a 0) b (+ (dec a) (inc b))))
|
||||
|
||||
(+ 4 5)
|
||||
(+ 3 6)
|
||||
(+ 2 7)
|
||||
(+ 1 8)
|
||||
(+ 0 9)
|
||||
9
|
||||
|
||||
Iterative
|
||||
|
||||
|
||||
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)
|
||||
(A 0 (A 1 9))
|
||||
(A 0 (A 0 (A 1 8)))
|
||||
(A 0 (A 0 (A 0 (A 1 7))))
|
||||
(A 0 (A 0 (A 0 (A 0 (A 1 6)))))
|
||||
(A 0 (A 0 (A 0 (A 0 (A 0 (A 1 5))))))
|
||||
(A 0 (A 0 (A 0 (A 0 (A 0 (A 0 (A 1 4)))))))
|
||||
(A 0 (A 0 (A 0 (A 0 (A 0 (A 0 (A 0 (A 1 3)))))))))
|
||||
(A 0 (A 0 (A 0 (A 0 (A 0 (A 0 (A 0 (A 0 (A 1 2))))))))))
|
||||
(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 4))))))))))
|
||||
(A 0 (A 0 (A 0 (A 0 (A 0 (A 0 (A 0 6)))))))))
|
||||
(A 0 (A 0 (A 0 (A 0 (A 0 (A 0 8)))))))
|
||||
(A 0 (A 0 (A 0 (A 0 (A 0 10))))))
|
||||
(A 0 (A 0 (A 0 (A 0 12)))))
|
||||
(A 0 (A 0 (A 0 14))))
|
||||
(A 0 (A 0 16)))
|
||||
(A 0 18)
|
||||
22
|
||||
|
||||
(A 2 4) = 16
|
||||
(A 3 3) = 16
|
||||
|
||||
|
||||
1.34
|
||||
|
||||
(define (f g) (g 2))
|
||||
|
||||
(f f) gives error Error: call of non-procedure: 2. This is because it is expecting the
|
||||
second argument to be a procedure (implicitly from the fact that it applies it to 2).
|
||||
|
||||
|
||||
1.35
|
||||
|
||||
Golden ratio: phi = (1 + sqrt(5))/2
|
||||
|
||||
Let x' be a fixed point of x |-> 1 + 1/x. Then
|
||||
|
||||
x' = 1 + 1/x' = (x' + 1)/x'
|
||||
x'^2 = x' + 1
|
||||
x'^2 - x' - 1 = 0
|
||||
|
||||
Solutions: (1 +- sqrt(1 + 4)) / 2. So phi is one of the fixed points.
|
Loading…
Reference in New Issue