Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

연습문제 풀이 03

3_01

;; file: 3_01.rkt

(#%require rackunit)

(define (make-accumulator initial-value)
  (let ((cached initial-value))
    (lambda (x)
      (set! cached (+ x cached))
      cached)))

(define A (make-accumulator 5))

(check-equal? (A 10) 15)
(check-equal? (A 10) 25)

3_02

;; file: 3_02.rkt

(#%require rackunit)

(define (make-monitored fn)
  (let ((call-count 0))
    (lambda (x)
      (if (eq? x 'how-many-calls?)
          call-count
          (let ((result (fn x)))
            (set! call-count (inc call-count))
            result)))))

(define s (make-monitored sqrt))

(check-equal? (s 100) 10)

(check-equal? (s 'how-many-calls?) 1)

3_03

;; file: 3_03.rkt
;; 3_03 / 3_04 / 3_07

(#%require rackunit)
(#%require (prefix racket: racket))
(racket:provide make-account)

(define (make-account balance initial-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 m)
    (cond ((eq? m 'withdraw) withdraw)
          ((eq? m 'deposit) deposit)
          (else (error "Unknown request -- MAKE-ACCOUNT"
                       m))))
  (define (password-dispatch password m)
    (if (not (eq? password initial-password))
        (lambda (amount)
          "Incorrect password")
        (dispatch m)))
  password-dispatch)

(define acc (make-account 100 'secret-password))

(check-equal? ((acc 'secret-password 'withdraw) 40) 60)

(check-equal? ((acc 'some-other-password 'deposit) 50) "Incorrect password")

3_04

;; file: 3_04.rkt
;; 3_03 / 3_04 / 3_07


(#%require rackunit)

(define (make-account balance initial-password)
  (define (withdraw amount)
    (if (>= balance amount)
        (begin (set! balance (- balance amount))
               balance)
        "Insufficient funds"))
  (define (deposit amount)
    (set! balance (+ balance amount))
    balance)
  (define (call-the-cops amount)
    'call-the-cops)
  (define (dispatch m)
    (cond ((eq? m 'withdraw) withdraw)
          ((eq? m 'deposit) deposit)
          ((eq? m 'call-the-cops) call-the-cops)
          (else (error "Unknown request -- MAKE-ACCOUNT"
                       m))))
  (let ((wrong-password-count 0))
    (define (password-dispatch password m)
      (if (not (eq? password initial-password))
          (begin
            (set! wrong-password-count (inc wrong-password-count))
            (if (>= wrong-password-count 7)
                (dispatch 'call-the-cops)
                (lambda (amount)
                  "Incorrect password")))
          (dispatch m)))
    
    password-dispatch))

(define acc (make-account 100 'secret-password))

(check-equal? ((acc 'secret-password 'withdraw) 40) 60)

(check-equal? ((acc 'some-other-password 'deposit) 50) "Incorrect password")
(check-equal? ((acc 'some-other-password 'deposit) 50) "Incorrect password")
(check-equal? ((acc 'some-other-password 'deposit) 50) "Incorrect password")
(check-equal? ((acc 'some-other-password 'deposit) 50) "Incorrect password")
(check-equal? ((acc 'some-other-password 'deposit) 50) "Incorrect password")
(check-equal? ((acc 'some-other-password 'deposit) 50) "Incorrect password")
(check-equal? ((acc 'some-other-password 'deposit) 50) 'call-the-cops)

3_05

;; file: 3_05.rkt

3_06

;; file: 3_06.rkt
(#%require rackunit)

(define (rand-update x)
  (let ((a 27) (b 26) (m 127))
    (modulo (+ (* a x) b) m)))

(define random-init 7)

(define rand
  (let ((x random-init))
    (define (reset new-value)
      (set! x new-value))
    (define (generate)
      (set! x (rand-update x))
      x)
    (define (dispatch m)
      (cond ((eq? m 'generate)
             (generate))
            ((eq? m 'reset)
             reset)))
    dispatch))


(check-equal? (rand 'generate) 88)
(check-equal? (rand 'generate) 116)
(check-equal? (rand 'generate) 110)

((rand 'reset) 7)

(check-equal? (rand 'generate) 88)
(check-equal? (rand 'generate) 116)
(check-equal? (rand 'generate) 110)

3_07

;; file: 3_07.rkt
;; 3_03 / 3_04 / 3_07
(#%require rackunit)
(#%require (prefix racket: racket))
(racket:require (racket:only-in "3_03.rkt" make-account))


(define (make-joint account account-password new-password)
  (define (dispatch password m)
    (if (not (eq? password new-password))
        (lambda (amount)
          "Incorrect password")
        (account account-password m)))
  dispatch)

(define peter-acc (make-account 100 'open-sesame))
(check-equal? ((peter-acc 'open-sesame 'withdraw) 40) 60)

(define paul-acc
  (make-joint peter-acc 'open-sesame 'rosebud))

(check-equal? ((paul-acc 'rosebud 'withdraw) 40) 20)

3_08

;; file: 3_08.rkt

(#%require rackunit)
(define make-f nil)
(define f nil)

(define (make-f-1)
  (let ((cached 'undefined))
    (define (inner-f x)
      (if (eq? cached 'undefined)
          (begin
            (set! cached x)
            x)
          0))
    inner-f))

(set! make-f make-f-1)
(set! f (make-f))
(check-equal? (let ((x (f 0))
                    (y (f 1)))
                (+ x y))
              0)
(set! f (make-f))
(check-equal? (let ((y (f 1))
                    (x (f 0)))
                (+ x y))
              1)


(define (make-f-2)
  ((lambda (old)
     (define (inner-f x)
       (let ((temp old))
         (set! old x)
         temp))
     inner-f)
   0))

(set! make-f make-f-2)
(set! f (make-f))
(check-equal? (let ((x (f 0))
                    (y (f 1)))
                (+ x y))
              0)
(set! f (make-f))
(check-equal? (let ((y (f 1))
                    (x (f 0)))
                (+ x y))
              1)

3_09

;; file: 3_09.rkt

3_10

;; file: 3_10.rkt

3_11

;; file: 3_11.rkt

3_12

;; file: 3_12.rkt
;; 3_12 / 5_22
(#%require rackunit)
(#%require "../allcode/helper/my-util.rkt")
(#%require (prefix racket: racket))
(#%require threading)

;; TODO

(define (append x y)
  (if (null? x)
      y
      (cons (car x) (append (cdr x) y))))

(define (append! x y)
  (set-cdr! (last-pair x) y)
  x)

(define (last-pair x)
  (if (null? (cdr x))
      x
      (last-pair (cdr x))))

(define x1 '(1 2))
(define y1 '(3 4))
(check-equal? (append x1 y1)
              '(1 2 3 4))
(check-equal? x1 '(1 2))
(check-equal? y1 '(3 4))

(define x2 '(1 2))
(define y2 '(3 4))
(check-equal? (append! x2 y2)
              '(1 2 3 4))
(check-equal? x2 '(1 2 3 4))
(check-equal? y2 '(3 4))

3_13

;; file: 3_13.rkt

3_14

;; file: 3_14.rkt

3_15

;; file: 3_15.rkt

3_16

;; file: 3_16.rkt

3_17

;; file: 3_17.rkt

3_18

;; file: 3_18.rkt

3_19

;; file: 3_19.rkt

3_20

;; file: 3_20.rkt

3_21

;; file: 3_21.rkt

3_22

;; file: 3_22.rkt

3_23

;; file: 3_23.rkt

3_24

;; file: 3_24.rkt

3_25

;; file: 3_25.rkt

3_26

;; file: 3_26.rkt

3_27

;; file: 3_27.rkt

3_28

;; file: 3_28.rkt

3_29

;; file: 3_29.rkt

3_30

;; file: 3_30.rkt

3_31

;; file: 3_31.rkt

3_32

;; file: 3_32.rkt

3_33

;; file: 3_33.rkt

3_34

;; file: 3_34.rkt

3_35

;; file: 3_35.rkt

3_36

;; file: 3_36.rkt

3_37

;; file: 3_37.rkt

3_38

;; file: 3_38.rkt

3_39

;; file: 3_39.rkt

3_40

;; file: 3_40.rkt

3_41

;; file: 3_41.rkt

3_42

;; file: 3_42.rkt

3_43

;; file: 3_43.rkt

3_44

;; file: 3_44.rkt

3_45

;; file: 3_45.rkt

3_46

;; file: 3_46.rkt

3_47

;; file: 3_47.rkt

3_48

;; file: 3_48.rkt

3_49

;; file: 3_49.rkt

3_50

;; file: 3_50.rkt

3_51

;; file: 3_51.rkt

3_52

;; file: 3_52.rkt

3_53

;; file: 3_53.rkt

3_54

;; file: 3_54.rkt

3_55

;; file: 3_55.rkt

3_56

;; file: 3_56.rkt

3_57

;; file: 3_57.rkt

3_58

;; file: 3_58.rkt

3_59

;; file: 3_59.rkt

3_60

;; file: 3_60.rkt

3_61

;; file: 3_61.rkt

3_62

;; file: 3_62.rkt

3_63

;; file: 3_63.rkt

3_64

;; file: 3_64.rkt

3_65

;; file: 3_65.rkt

3_66

;; file: 3_66.rkt

3_67

;; file: 3_67.rkt

3_68

;; file: 3_68.rkt

3_69

;; file: 3_69.rkt

3_70

;; file: 3_70.rkt

3_71

;; file: 3_71.rkt

3_72

;; file: 3_72.rkt

3_73

;; file: 3_73.rkt

3_74

;; file: 3_74.rkt

3_75

;; file: 3_75.rkt

3_76

;; file: 3_76.rkt

3_77

;; file: 3_77.rkt

3_78

;; file: 3_78.rkt

3_79

;; file: 3_79.rkt

3_80

;; file: 3_80.rkt

3_81

;; file: 3_81.rkt

3_82

;; file: 3_82.rkt