Created
August 29, 2021 15:27
-
-
Save kurtbrose/98a2bf899070678827f3528070aabbda to your computer and use it in GitHub Desktop.
working my way through structure and interpretation of computer programs, ch 3
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#lang sicp | |
(define balance 100) | |
(define (withdraw amount) | |
(if (>= balance amount) | |
(begin (set! balance (- balance amount)) | |
balance) | |
"Insufficient funds")) | |
(define new-withdraw | |
(let ((balance 100)) | |
(lambda (amount) | |
(if (>= balance amount) | |
(begin (set! balance (- balance amount)) | |
balance) | |
"Insufficient funds")))) | |
(define (make-withdraw balance) | |
(lambda (amount) | |
(if (>= balance amount) | |
(begin (set! balance (- balance amount)) | |
balance) | |
"Insufficient funds"))) | |
(define (make-account balance) | |
(define (withdraw amount) | |
(if (>= balance amount) | |
(begin (set! balance (- balance amount)) | |
balance) | |
"Insufficient funds")) | |
(define (deposit amount) | |
(set! balance (+ balance amount)) | |
balance) | |
(define (dispatch m) | |
(cond ((eq? m 'withdraw) withdraw) | |
((eq? m 'deposit) deposit) | |
(else (error "Unknown request -- MAKE-ACCOUNT" | |
m)))) | |
dispatch) | |
; exercise 3.1 | |
(define (make-accumulator acc) | |
(define (accumulate amt) | |
(set! acc (+ acc amt)) | |
acc) | |
accumulate) | |
; exercise 3.2 | |
(define (make-monitored f) | |
(let ((n 0)) | |
(lambda (arg) | |
(if (eq? arg 'how-many-calls?) | |
n | |
(begin | |
(set! n (+ n 1)) | |
(f arg)))))) | |
; exercise 3.3 | |
(define (make-account2 balance password) | |
(define (withdraw amount) | |
(if (>= balance amount) | |
(begin (set! balance (- balance amount)) | |
balance) | |
"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 (error "Unknown request -- MAKE-ACCOUNT" | |
m))) | |
(error "Incorrect password"))) | |
dispatch) | |
; exercise 3.4 | |
(define (make-account3 balance password) | |
(define consecutive-wrong-pw 0) | |
(define (withdraw amount) | |
(if (>= balance amount) | |
(begin (set! balance (- balance amount)) | |
balance) | |
"Insufficient funds")) | |
(define (deposit amount) | |
(set! balance (+ balance amount)) | |
balance) | |
(define (dispatch pw m) | |
(if (eq? pw password) | |
(begin | |
(set! consecutive-wrong-pw 0) | |
(cond ((eq? m 'withdraw) withdraw) | |
((eq? m 'deposit) deposit) | |
(else (error "Unknown request -- MAKE-ACCOUNT" | |
m)))) | |
(begin | |
(set! consecutive-wrong-pw (+ consecutive-wrong-pw 1)) | |
(if (eq? consecutive-wrong-pw 7) | |
(error "call-the-cops") | |
(error "Incorrect password"))))) | |
dispatch) | |
(define (rand-update x) | |
(remainder (+ (* 13 x) 5) 24)) | |
(define random-init (rand-update (expt 2 32))) | |
(define rand | |
(let ((x random-init)) | |
(lambda () | |
(set! x (rand-update x)) | |
x))) | |
(define (estimate-pi trials) | |
(sqrt (/ 6 (monte-carlo trials cesaro-test)))) | |
(define (cesaro-test) | |
(= (gcd (rand) (rand)) 1)) | |
(define (monte-carlo trials experiment) | |
(define (iter trials-remaining trials-passed) | |
(cond ((= trials-remaining 0) | |
(/ trials-passed trials)) | |
((experiment) | |
(iter (- trials-remaining 1) (+ trials-passed 1))) | |
(else | |
(iter (- trials-remaining 1) trials-passed)))) | |
(iter trials 0)) | |
(define (random-in-range low high) | |
(let ((range (- high low))) | |
(+ low (random range)))) | |
; exercise 3.5 | |
(define (estimate-integral P x1 x2 y1 y2 trials) | |
(define (iter trials-remaining trials-passed) | |
(if (< trials-remaining 0) | |
(/ trials-passed trials) | |
(iter ;not a tail-call, but more readable this way | |
(- trials-remaining 1) | |
(+ trials-passed | |
(if (P (random-in-range x1 x2) (random-in-range y1 y2)) | |
1 | |
0)))) | |
) | |
(iter trials 0)) | |
; measure area of unit circle with estimate-integral | |
(define (sum vs) (if (eq? vs nil) 0 (+ (car vs) (sum (cdr vs))))) | |
(define (sum2 vs) (apply + vs)) | |
(define (vector-len vs) | |
(define (sq x) (* x x)) | |
(sum (map sq vs))) | |
(define unit-circle-area | |
(estimate-integral | |
(lambda (x y) (< (vector-len (list x y)) 1)) | |
-1 1 -1 1 10000)) | |
; exercise 3.6 | |
(define rand2 | |
(let ((x random-init)) | |
(lambda (cmd) | |
(cond | |
((eq? cmd `generate) | |
(set! x (rand-update x)) | |
x) | |
((eq? cmd `reset) | |
(lambda (x_) (set! x x_))))))) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment