aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJacques Comeaux <jacquesrcomeaux@protonmail.com>2023-07-11 22:59:47 -0500
committerJacques Comeaux <jacquesrcomeaux@protonmail.com>2023-07-11 22:59:47 -0500
commit54c9fa0ebc437766698b05ee698e745eb59ca6c1 (patch)
tree4da4e7ed3ec7ac631f3da21b1b0af5ba3b1d2c4f
parentd00ad13ac6d7474446de49524102c0e0dc084d58 (diff)
Add chapter 3 part 1
-rw-r--r--chap3/part1.rkt283
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)))))