diff options
author | Jacques Comeaux <jacquesrcomeaux@protonmail.com> | 2023-07-11 22:59:47 -0500 |
---|---|---|
committer | Jacques Comeaux <jacquesrcomeaux@protonmail.com> | 2023-07-11 22:59:47 -0500 |
commit | 54c9fa0ebc437766698b05ee698e745eb59ca6c1 (patch) | |
tree | 4da4e7ed3ec7ac631f3da21b1b0af5ba3b1d2c4f | |
parent | d00ad13ac6d7474446de49524102c0e0dc084d58 (diff) |
Add chapter 3 part 1
-rw-r--r-- | chap3/part1.rkt | 283 |
1 files changed, 283 insertions, 0 deletions
diff --git a/chap3/part1.rkt b/chap3/part1.rkt new file mode 100644 index 0000000..a0fc71f --- /dev/null +++ b/chap3/part1.rkt @@ -0,0 +1,283 @@ +#lang sicp +(#%require (only racket/base print-as-expression print-mpair-curly-braces)) +(print-as-expression #f) +(print-mpair-curly-braces #f) + +;; Chapter 3 +;; Modularity, Objects, and State + +;; 3.1 +;; Assignment and Local State + +(define balance 100) + +(#%provide withdraw) +(define (withdraw amount) + (if (>= balance amount) + (begin + (set! balance (- balance amount)) + balance) + "Insufficient funds")) + +(#%provide new-withdraw) +(define new-withdraw + (let ((balance 100)) + (lambda (amount) + (if (>= balance amount) + (begin + (set! balance (- balance amount)) + balance) + "Insufficient funds")))) + +(#%provide make-withdraw) +(define (make-withdraw balance) + (lambda (amount) + (if (>= balance amount) + (begin + (set! balance (- balance amount)) + balance) + "Insufficient funds"))) + +(#%provide make-account) +(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) + +#| 3.1 |# + +(#%provide make-accumulator) +(define (make-accumulator sum) + (lambda (x) + (begin + (set! sum (+ sum x)) + sum))) + +#| 3.2 |# + +(#%provide make-monitored) +(define (make-monitored f) + (let ((call-count 0)) + (lambda (arg) + (cond + ((and (symbol? arg) (eq? arg 'how-many-calls?)) + call-count) + ((and (symbol? arg) (eq? arg 'reset-count)) + (set! call-count 0)) + (else + (set! call-count (+ call-count 1)) + (f arg)))))) + +#| 3.3 |# + +(#%provide make-account-pass) +(define (make-account-pass balance secret-pass) + (define (withdraw amount) + (if (>= balance amount) + (begin + (set! balance (- balance amount)) + balance) + "Insufficient funds")) + (define (deposit amount) + (set! balance (+ balance amount)) + balance) + (define (dispatch pass m) + (if (eq? pass secret-pass) + (cond + ((eq? m 'withdraw) withdraw) + ((eq? m 'deposit) deposit) + (else (error "Unknown request -- MAKE-ACCOUNT" m))) + (error "Incorrect password"))) + dispatch) + +#| 3.4 |# + +(define (call-the-cops) + (display "WEEOOOWEEOOOWEEOOOOWEEOO") + (newline) + (display "STEP OUT OF THE VEHICLE") + (newline)) + +(#%provide make-account-pass-cops) +(define (make-account-pass-cops balance secret-pass) + (define fail-amount 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 pass m) + (if (eq? pass secret-pass) + (begin + (set! fail-amount 0) + (cond + ((eq? m 'withdraw) withdraw) + ((eq? m 'deposit) deposit) + (else (error "Unknown request -- MAKE-ACCOUNT" m)))) + (begin + (set! fail-amount (+ fail-amount 1)) + (if (> fail-amount 7) (call-the-cops)) + (error "Incorrect password")))) + dispatch) + +#| (define random-init 4) |# + +#| (define rand |# +#| (let ((x random-init)) |# +#| (lambda () |# +#| (set! x (rand-update x)) |# +#| x))) |# + +(#%provide estimate-pi) +(define (estimate-pi trials) + (sqrt (/ 6 (monte-carlo trials cesaro-test)))) + +(define (cesaro-test) + (= (gcd (random 10000) (random 10000)) 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)) + +#| 3.5 |# + +(define (square x) (* x x)) + +(define (random-in-range low high) + (let ((range (- high low))) + (+ low (random range)))) + +(#%provide estimate-pi-integral) +(define (estimate-pi-integral trials) + (* + 4 + (estimate-integral + (lambda (x y) (<= (+ (square x) (square y)) 1.0)) + 0 1.0 + 0 1.0 + trials))) + +(define (estimate-integral P x1 x2 y1 y2 trials) + (* + (- x2 x1) + (- y2 y1) + (monte-carlo + trials + (lambda () + (P + (random-in-range x1 x2) + (random-in-range y1 y2)))))) + +#| 3.6 |# + +(define random-init 4) + +(define (rand-update x) + (modulo (+ (* 75 x) 74) 65537)) + +(#%provide rand-new) +(define rand-new + (let ((x random-init)) + (lambda (sym) + (cond + ((eq? sym 'generate) + (set! x (rand-update x)) + x) + ((eq? sym 'reset) + (lambda (new-value) + (set! x new-value))) + (else error "unknown symbol"))))) + +(#%provide factorial) +(define (factorial n) + (let + ((product 1) + (counter 1)) + (define (iter) + (if (> counter n) + product + (begin + (set! product (* counter product)) + (set! counter (+ counter 1)) + (iter)))) + (iter))) + +(#%provide factorial-bad) +(define (factorial-bad n) + (let + ((product 1) + (counter 1)) + (define (iter) + (if (> counter n) + product + (begin + (set! counter (+ counter 1)) + (set! product (* counter product)) + (iter)))) + (iter))) + +#| 3.7 |# + +(#%provide make-account-pass-) +(define (make-account-pass- balance secret-pass) + (define (withdraw amount) + (if (>= balance amount) + (begin + (set! balance (- balance amount)) + balance) + "Insufficient funds")) + (define (deposit amount) + (set! balance (+ balance amount)) + balance) + (define (dispatch pass) + (if (eq? pass secret-pass) + (lambda (m) + (cond + ((eq? m 'withdraw) withdraw) + ((eq? m 'deposit) deposit) + (else (error "Unknown request -- MAKE-ACCOUNT" m)))) + (error "Incorrect password"))) + dispatch) + +(#%provide make-joint) +(define (make-joint acc old-pass new-pass) + (define inner-account (acc old-pass)) + (define (dispatch pass) + (lambda (m) + (if (eq? pass new-pass) + (inner-account m) + (error "Incorrect password")))) + dispatch) + +#| 3.8 |# + +(#%provide f) +(define f + (let ((init false)) + (lambda (x) + (if init + 0 + (begin (set! init true) x))))) |