Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #lang racket
- ;;;;;;;;;
- ;; 3.1 ;;
- ;;;;;;;;;
- (define (make-accumulator total)
- (lambda (amount)
- (set! total (+ total amount))
- total))
- ;; tests
- (define A (make-accumulator 5))
- (A 10)
- ;; 15
- (A 10)
- ;; 25
- ;;;;;;;;;
- ;; 3.2 ;;
- ;;;;;;;;;
- (define (make-monitored f)
- (define num-calls 0)
- (lambda (input)
- (cond [(equal? input 'how-many-calls?) num-calls]
- [(equal? input 'reset-num-calls) (set! num-calls 0)]
- [else (set! num-calls (add1 num-calls))
- (f input)])))
- ;; tests
- (define s (make-monitored sqrt))
- (s 100)
- ;; 10
- (s 81)
- ;; 9
- (s 64)
- ;; 8
- (s 'how-many-calls?)
- ;; 3
- (s 'reset-num-calls)
- (s 'how-many-calls?)
- ;; 0
- ;;;;;;;;;
- ;; 3.3 ;;
- ;;;;;;;;;
- (define (display-error message)
- (lambda (amount) message))
- (define (make-account balance password)
- (define (withdraw amount)
- (cond [(>= balance amount)
- (set! balance (- balance amount))
- balance]
- [else "Insufficient funds"]))
- (define (deposit amount)
- (set! balance (+ balance amount))
- balance)
- (define (dispatch pw m)
- (if (eq? pw password)
- (cond [(eq? m 'withdraw) withdraw]
- [(eq? m 'deposit) deposit]
- [else (display-error "Unknown request -- MAKE-ACCOUNT")])
- (display-error "Incorrect password")))
- dispatch)
- ;; tests
- (define acc (make-account 100 'abc))
- ((acc 'abc 'deposit) 100)
- ;; 200
- ((acc 'abc 'withdraw) 50)
- ;; 150
- ((acc 'abc 'withdraw) 200)
- ;; "Insufficient funds"
- ((acc 'xyz 'withdraw) 1000000)
- ;; "Incorrect password"
- ((acc 'abc 'invest) 1000)
- ;; "Unknown request -- MAKE-ACCOUNT"
- ((acc 'abc 'deposit) 25)
- ;; 175
- ;;;;;;;;;
- ;; 3.4 ;;
- ;;;;;;;;;
- (define (make-secure-account balance password)
- (define number-wrong-guesses 0)
- (define (call-the-cops)
- (display-error "The police have been called"))
- (define (withdraw amount)
- (cond [(>= balance amount)
- (set! balance (- balance amount))
- balance]
- [else "Insufficient funds"]))
- (define (deposit amount)
- (set! balance (+ balance amount))
- balance)
- (define (dispatch pw m)
- (cond [(eq? pw password)
- (set! number-wrong-guesses 0)
- (cond [(eq? m 'withdraw) withdraw]
- [(eq? m 'deposit) deposit]
- [else (display-error "Unknown request -- MAKE-ACCOUNT")])]
- [(< number-wrong-guesses 7)
- (set! number-wrong-guesses (add1 number-wrong-guesses))
- (display-error "Incorrect password")]
- [else (call-the-cops)]))
- dispatch)
- ;; tests
- (define new-acc (make-secure-account 100 'abc))
- ((new-acc 'abc 'deposit) 50)
- ;; 150
- ((new-acc 'xyz1 'withdraw) 1000000)
- ;; "Incorrect password"
- ((new-acc 'xyz2 'withdraw) 1000000)
- ;; "Incorrect password"
- ((new-acc 'xyz3 'withdraw) 1000000)
- ;; "Incorrect password"
- ((new-acc 'xyz4 'withdraw) 1000000)
- ;; "Incorrect password"
- ((new-acc 'xyz5 'withdraw) 1000000)
- ;; "Incorrect password"
- ((new-acc 'xyz6 'withdraw) 1000000)
- ;; "Incorrect password"
- ((new-acc 'xyz7 'withdraw) 1000000)
- ;; "Incorrect password"
- ((new-acc 'xyz8 'withdraw) 1000000)
- ;; "The police have been called"
- ;;;;;;;;;
- ;; 3.5 ;;
- ;;;;;;;;;
- (define (inexact-random low high)
- ; Return a random inexact real in the interval (low, high).
- (+ low (* (random) (- high low))))
- (define (monte-carlo trials experiment)
- (define (iter trials-remaining trials-passed)
- ;; (printf "~a ~a ~n" trials-remaining trials-passed)
- (cond [(zero? trials-remaining)
- (exact->inexact (/ trials-passed trials))]
- [else
- (define hit (experiment))
- (if hit
- (iter (sub1 trials-remaining) (add1 trials-passed))
- (iter (sub1 trials-remaining) trials-passed))]))
- (iter trials 0))
- (define (estimate-integral predicate x1 x2 y1 y2 num-trials)
- (define total-area (* (- x2 x1) (- y2 y1)))
- (define (integral-experiment)
- (define x (inexact-random x1 x2))
- (define y (inexact-random y1 y2))
- (predicate x y))
- (* (monte-carlo num-trials integral-experiment)
- total-area))
- (define (estimate-pi num-trials)
- (define (in-unit-circle? x y)
- (< (+ (sqr x) (sqr y)) 1))
- (estimate-integral in-unit-circle? -1 1 -1 1 num-trials))
- ;; tests
- (estimate-pi 10)
- ;; 3.6
- (estimate-pi 100)
- ;; 3.2
- (estimate-pi 1000)
- ;; 3.176
- (estimate-pi 10000)
- ;; 3.1492
- (estimate-pi 100000)
- ;; 3.14252
- (estimate-pi 1000000)
- ;; 3.14344
- ;;;;;;;;;
- ;; 3.6 ;;
- ;;;;;;;;;
- ;; We'll use our own very simple prng: x[n+1] = 23 * x[n] + 11 mod 493.
- (define (make-resettable-prng seed)
- (define (rand-update x) (remainder (+ (* 23 x) 11) 493))
- (define x seed)
- (lambda (m)
- (cond [(eq? m 'generate)
- (set! x (rand-update x))
- x]
- [(eq? m 'reset)
- (set! x seed)
- "Reset."]
- [else "Unknown request -- RAND"])))
- (define new-prng (make-resettable-prng 10))
- ;; tests
- (new-prng 'generate)
- ;; 241
- (new-prng 'generate)
- ;; 131
- (new-prng 'generate)
- ;; 66
- (new-prng 'reset)
- ;; "Reset."
- (new-prng 'generate)
- ;; 241
- (new-prng 'generate)
- ;; 131
- (new-prng 'generate)
- ;; 66
- ;;;;;;;;;
- ;; 3.7 ;;
- ;;;;;;;;;
- (define (make-joint account password new-password)
- (if (number? ((account password 'deposit) 0)) ; deposit 0 to check original pw
- (lambda (pass m)
- (if (eq? pass new-password)
- (account password m)
- (display-error "Incorrect password")))
- "Password does not match -- MAKE-JOINT"))
- (define paul-acc (make-account 100 'abc))
- ((paul-acc 'abc 'deposit) 100)
- ;; 200
- (define mary-acc (make-joint paul-acc 'abc 'def))
- ((mary-acc 'def 'withdraw) 75)
- ;; 125
- ((mary-acc 'def 'deposit) 50)
- ;; 175
- ((mary-acc 'xyz 'withdraw) 1000000)
- ;; "Incorrect password"
- (make-joint mary-acc 'xyz 'def)
- ;; "Password does not match -- MAKE-JOINT"
- ;;;;;;;;;
- ;; 3.8 ;;
- ;;;;;;;;;
- (define (make-weird-function)
- (define state 0)
- (lambda (n)
- (cond
- [(and (even? state) (even? n)) (set! state (add1 state)) -1]
- [(and (odd? state) (odd? n)) (set! state (add1 state)) 1]
- [(and (even? state) (odd? n)) (set! state (add1 state)) 1]
- [(and (odd? state) (even? n)) (set! state (add1 state)) 0])))
- ;; test
- (define f (make-weird-function))
- (f 0)
- ;; -1
- (f 1)
- ;; 1
- ;; So evaluating (+ (f 0) (f 1)) left to right would produce (+ -1 1) or zero.
- (define g (make-weird-function))
- (g 1)
- ;; 1
- (g 0)
- ;; 0
- ;; So evaluating (+ (g 0) (g 1)) right to left would produce (+ 1 0) or one.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement