SICP勉強会(1)
SICP勉強会をした。やった範囲は3.1.1から3.2.1まで。
書いたコード
; 3.1.1 --------------------------------------------------- (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) ; ex 3.1 (define (make-accumulator sum) (lambda (n) (set! sum (+ sum n)) sum)) ; ex 3.2 (define (make-monitored f) (let ((count 0)) (lambda (x) (cond ((eq? x 'how-many-calls?) count) ((eq? x 'reset-count) (set! count 0)) (else (set! count (+ count 1)) (f x)))))) ; ex 3.3 (define (make-account 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 p m) (cond ((not (eq? p password)) (lambda (x) "Incorrect password")) ((eq? m 'withdraw) withdraw) ((eq? m 'deposit) deposit) (else (error "Unknown request -- MAKE-ACCOUNT" m)))) dispatch) ; ex 3.4 (define (call-the-cops) "CALL-THE-COPS!!") (define (make-account balance password) (define (withdraw amount) (if (>= balance amount) (begin (set! balance (- balance amount)) balance) "Insufficient funds")) (define (deposit amount) (set! balance (+ balance amount)) balance) (let ((fail-count 0)) (define (dispatch p m) (cond ((not (eq? p password)) (set! fail-count (+ fail-count 1)) (if (>= fail-count 7) (lambda (x) (call-the-cops)) (lambda (x) "Incorrect password"))) ((eq? m 'withdraw) (set! fail-count 0) withdraw) ((eq? m 'deposit) (set! fail-count 0) deposit) (else (error "Unknown request -- MAKE-ACCOUNT" m)))) dispatch)) ; 3.1.2 --------------------------------------------------- (define (rand-update x) (modulo (+ (* x 1103515245) 12345) 2147483648)) (define random-init 56243) (define rand (let ((x random-init)) (lambda () (set! x (rand-update x)) x))) (define (random x) (* x (/ (rand) 2147483648))) (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)) ; ex 3.5 (define (unit-circle x y) (< (+ (* x x) (* y y)) 1.0)) (define (random-in-range low high) (let ((range (- high low))) (+ low (random range)))) (define (estimate-integral pred x1 y1 x2 y2 trials) (monte-carlo trials (lambda () (pred (random-in-range x1 x2) (random-in-range y1 y2))))) (define (estimate-pi trials) (* 4.0 (estimate-integral unit-circle 0 0 1.0 1.0 trials))) ; ex 3.6 (define rand2 (let ((x random-init)) (lambda (operate) (cond ((eq? operate 'generate) (set! x (rand-update x)) x) ((eq? operate 'reset) (lambda (new-value) (set! x new-value))) (else (error "Invalid operation -- RAND2")))))) ; 3.1.3 --------------------------------------------------- ; ex 3.7 (define (make-account 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 p m) (cond ((eq? m 'correct-password?) (eq? p password)) ((not (eq? p password)) (lambda (x) "Incorrect password")) ((eq? m 'withdraw) withdraw) ((eq? m 'deposit) deposit) (else (error "Unknown request -- MAKE-ACCOUNT" m)))) dispatch) (define (make-joint acc password new-password) (define (dispatch p m) (cond ((eq? m 'correct-password) (eq? p new-password)) ((not (eq? p new-password)) (lambda (x) "Incorrect password")) ((eq? m 'withdraw) (acc password 'withdraw)) ((eq? m 'deposit) (acc password 'deposit)) (else (error "Unknown request -- MAKE-JOINT" m)))) (if (acc password 'correct-password?) dispatch "Incorrect password")) ; ex 3.8 (define f (let ((y 0)) (lambda (x) (if (= y 0) (begin (set! y 1) x) 0))))