sicp exercise ch3 - andstudy/forge GitHub Wiki

kukuman

연습문제 3.1

    ( define (make-accumulator default)
      ( lambda (addend)
        ( begin (set! default (+ default addend))
                default
         ))
       )
    
    (define A (make-accumulator 5))
    (A 10)
    (A 10)

연습문제 3.2

    ( define (make-monitored fun)        
       (  let (( counte 0))  
       (  define ( call-and-add param )       
                
            ( begin (set! counte (+ counte 1)) 
                    (fun param) ))
         ( define ( how-many-calls) 
            counte)
         ( define (dispatch m )
            (cond  (( eq? m 'how-many-calls?) (how-many-calls) )
                 ( else ( call-and-add m ))))
         dispatch
      ))
    
    (define s (make-monitored sqrt))
    
    (s 100)
    (s 'how-many-calls?)
    (s 100)
    (s 100)
    (s 'how-many-calls?)

연습문제 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 input m )
        (if ( eq? password input)
         (cond ((eq? m 'withdraw) withdraw)
              ((eq? m 'deposit) deposit)
              (else (error "Unknown request -- MAKE-ACCOUNT"
                           m)))
          ( error "Incorrect passwd" ) 
         ))
      dispatch)
      
    
      
    
    
                           
    (define acc (make-account 100 'secret-password))
    ((acc 'secret-password 'withdraw) 40)
    ((acc 'some-other-password 'deposit) 50)

연습문제 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 input m )
        ( if (eq? m 'pwd-ok)
             (pwd-ok input)
             (if ( eq? password input)
         (cond ((eq? m 'withdraw) withdraw)
              ((eq? m 'deposit) deposit)
              (else (error "Unknown request -- MAKE-ACCOUNT"
                           m)))
          ( error "Incorrect passwd" ) 
         )))
      (define (pwd-ok input) (eq? input password)
        )
        dispatch)
    
    (define (make-joint acct acct-pwd new-pwd)
       (define (dispatch pwd m) 
         ( if (eq? new-pwd pwd)
         (acct acct-pwd m) 
         ( error "invalid new-passwd")))
      (cond ( (acct acct-pwd 'pwd-ok)         dispatch)
               ( else ( error "invalid org passwd!" )))
      ) 
    
      
      
    
    (define  peter-acc (make-account 100 'open-sesame))   
    
    (define paul-acc
      (make-joint peter-acc 'open-sesame 'rosebud))
    
    ( (paul-acc 'rosebud 'withdraw) 49)

ohyecloudy

Exercise 3.1

    (define (make-accumulator accumulation)
      (lambda (num)
        (begin (set! accumulation (+ accumulation num))
               accumulation)))

Exercise 3.2

    (define (make-monitored f)
      (define count 0)
      (define (dispatch m)
        (cond ((eq? m 'reset-count) (begin (set! count 0) count))
              ((eq? m 'how-many-calls?) count)
              (else (begin (set! count (+ count 1)) (f m)))))
      dispatch)

Exercise 3.3

    (define (make-account balance password)
      (lambda (input-password m)
        (define (withdraw amount)
          (if (>= balance amount)
              (begin (set! balance (- balance amount))
                     balance)
              "Insufficient funds"))
        (define (deposit amount)
          (begin (set! balance (+ balance amount))
                 balance))
        (define (wrong-password dummy)
          "Incorrect password")
        (define (dispatch m)
          (cond ((eq? m 'withdraw) withdraw)
                ((eq? m 'deposit) deposit)
                (else (error "Unknown request -- MAKE-ACCOUNT"
                             m))))
        (cond ((eq? input-password password) (dispatch m))
              (else wrong-password))))

Exercise 3.4

    (define (make-account balance password)
      (define wrong-count 0)
      (lambda (input-password m)
        (define (withdraw amount)
          (if (>= balance amount)
              (begin (set! balance (- balance amount))
                     balance)
              "Insufficient funds"))
        (define (deposit amount)
          (begin (set! balance (+ balance amount))
                 balance))
        (define (wrong-password dummy)
          (begin (set! wrong-count (+ wrong-count 1))
          wrong-count)
          (if (> wrong-count 7) "call-the-cops"
              "Incorrect password"))
        (define (dispatch m)
          (cond ((eq? m 'withdraw) withdraw)
                ((eq? m 'deposit) deposit)
                (else (error "Unknown request -- MAKE-ACCOUNT"
                             m))))
        (cond ((eq? input-password password)
               (begin (set! wrong-count 0);패스워드가 맞으면 틀린 카운트를 초기화 한다.
                      (dispatch m)))
              (else wrong-password))))

Exercise 3.5

    ;; random ----
    (define (random-in-range low high)
      (let ((range (- high low)))
        (+ low (random-real range))))
    
    (define (random-real range) (* range (random)))
    
    ;; estimate-integral ----
    (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.0)) ; 소수로 나타내기 위해서.
    
    (define (estimate-integral p x1 x2 y1 y2 trials)
      (let ((width (- x2 x1))
            (height (- y2 y1)))        
        (* (monte-carlo trials p)
           (* width height))))
    
    (define (unit-circle-test)
      (define (square x) (* x x))
      (let ((rand-x (random-in-range -1 1))
            (rand-y (random-in-range -1 1)))
        (<= (+ (square rand-x) (square rand-y)) 1)))
    
    ;; test ----
    (estimate-integral unit-circle-test -1 1 -1 1 10000)

Exercise 3.6

    ; rand-update from SICP homepage
    (define (rand-update x)
      (let ((a 27) (b 26) (m 127))
        (modulo (+ (* a x) b) m)))
    
    (define rand-init 0)
    
    (define rand
      (let ((x rand-init))
        (define (dispatch m)
          (cond ((eq? m 'generate)
                 (set! x (rand-update x))
                 x)
                ((eq? m 'reset)
                 (lambda (reset-num)
                   (set! x reset-num)
                   x))))
        dispatch))
    
    ;; test ----
    (rand 'generate)
    (rand 'generate)
    (rand 'generate)
    ((rand 'reset) 0)
    (rand 'generate)

bt22d

연습문제 3.1

    (define (make-accumulator acc-value)
      (lambda (elem)
        (begin (set! acc-value (+ acc-value elem))
    	   acc-value)))
    (define A (make-accumulator 5))

연습문제 3.2

    (define (make-monitored f)
      (let ((call-num 0))
        (define (mf arg)
          (cond ((eq? arg 'how-many-calls?) call-num)
                ((eq? arg 'reset-count) (set! call-num 0) call-num)
                (else (set! call-num (+ call-num 1)) (f arg))))
        mf))
    (define s (make-monitored sqrt))
    (s 100)
    (s 'how-many-calls?)
    (s 'reset-count)

연습문제 3.3

    (define (make-account balance passwd)
      (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 (not (eq? pw passwd))
            (lambda x "Incorrect password")
            (cond ((eq? m 'withdraw) withdraw)
                  ((eq? m 'deposit) deposit)
                  (else (error "Unknown request -- MAKE-ACCOUNT"
    			   m)))))
      dispatch)
    
    (define acc (make-account 100 'secret-password))
    
    ((acc 'secret-password 'withdraw) 30)
    ((acc 'wrong-pass 'withdraw) 30)
    ((acc 'secret-password 'deposit) 150)

연습문제 3.4

    (define (make-account balance passwd)
      (let ((num-wrong-input 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 passwd)
    	(cond ((eq? m 'withdraw) withdraw)
    	      ((eq? m 'deposit) deposit)
    	      (else (error "Unknown request -- MAKE-ACCOUNT"
    			   m)))
    	(begin (set! num-wrong-input (+ num-wrong-input 1))
    	       (lambda x (if (> num-wrong-input 7)
    			     "call-the-cops"
    			     "Incorrect password")))))
      dispatch))
    
    (define acc (make-account 100 'secret-password))
    
    ((acc 'secret-password 'withdraw) 30)
    ((acc 'wrong-pass 'withdraw) 30)
    ((acc 'secret-password 'deposit) 150)

연습문제 3.5

    (define (square x)
      (* x x))
    
    (define (sum-of-squares x y)
      (+ (square x) (square y)))
    
    (define (random-in-range low high)
      (let ((range (- high low)))
        (+ low (random range))))
    
    (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.0))
    
    (define (area x1 x2 y1 y2)
      (* (- x2 x1) (- y2 y1)))
    
    (define (estimate-integral P x1 x2 y1 y2 trials)
      (define (fn-P)
          (P (random-in-range x1 x2) (random-in-range y1 y2)))
      (* (area x1 x2 y1 y2) (monte-carlo trials fn-P)))
    
    (define (P x y)
      (<= (sum-of-squares (- x 5) (- y 7)) 
          (square 3)))
    
    (estimate-integral P 2 8 4 10 10000)