Skip to content

Instantly share code, notes, and snippets.

@kurtbrose
Created August 29, 2021 15:27
Show Gist options
  • Save kurtbrose/98a2bf899070678827f3528070aabbda to your computer and use it in GitHub Desktop.
Save kurtbrose/98a2bf899070678827f3528070aabbda to your computer and use it in GitHub Desktop.
working my way through structure and interpretation of computer programs, ch 3
#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