問題3.7 – SICP(計算機プログラムの構造と解釈)その109
2009年02月23日
問題3.7
最初に考えた解答
パスワードをリストにして、複数のパスワードが利用出来るようにする。
パスワード追加手続き add-password
を定義する。
パスワードのリストから一致するパスワードを探す correct-password?
を定義する。
(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 (add-password new-password) (set! password (cons new-password password)) password) (define (correct-password? pass) (memq pass password)) (define (dispatch pass m) (if (correct-password? pass) (cond ((eq? m 'withdraw) withdraw) ((eq? m 'deposit) deposit) ((eq? m 'addpassword) add-password) (else (error "Unknown request -- MAKE-ACCOUNT" m))) (error "Incorrect Password" pass))) dispatch) ;; 共同口座を作る手続き make-joint (define (make-joint account account-password new-password) (begin ((account account-password 'addpassword) new-password) account))
実行結果
一見上手くいったかと思ったけれど、お互いのパスワードを使うことができてしまう。
;; peter の口座 (define peter-acc (make-account 100 '(open-sesame))) ((peter-acc 'open-sesame 'withdraw) 20) gosh> 80 ;; paul の口座 (define paul-acc (make-joint peter-acc 'open-sesame 'rosebud)) ((paul-acc 'rosebud 'withdraw) 20) gosh> 60 ((peter-acc 'open-sesame 'deposit) 20) gosh> 80 ((paul-acc 'rosebud 'withdraw) 30) gosh> 50 ((peter-acc 'open-sesame 'withdraw) 30) gosh> 20 ((paul-acc 'open-sesame 'withdraw) 10) gosh> 10 ((peter-acc 'rosebud 'withdraw) 10) gosh> 0
パスワードの使い回しができないようにした解答
make-account
には手を加えずに、make-joint
で追加口座のパスワードを管理する。
(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 pass m) (if (eq? pass password) (cond ((eq? m 'withdraw) withdraw) ((eq? m 'deposit) deposit) (else (error "Unknown request -- MAKE-ACCOUNT" m))) (error "Incorrect Password" pass))) dispatch) (define (make-joint account account-password new-password) (define (dispatch password m) (if (eq? password new-password) (account account-password m) (error "Incorrect password" account-password))) dispatch)
実行結果
;; peter の口座 (define peter-acc (make-account 100 'open-sesame)) ((peter-acc 'open-sesame 'withdraw) 20) gosh> 80 ;; paul の口座 (define paul-acc (make-joint peter-acc 'open-sesame 'rosebud)) ((paul-acc 'rosebud 'withdraw) 10) gosh> 70 ((paul-acc 'rosebud 'deposit) 10) gosh> 80 ((paul-acc 'open-sesame 'deposit) 10) gosh> *** ERROR: Incorrect password open-sesame ((peter-acc 'rosebud 'withdraw) 10) gosh> *** ERROR: Incorrect Password rosebud
計算機プログラムの構造と解釈
posted with amazlet at 08.11.07
ジェラルド・ジェイ サスマン ジュリー サスマン ハロルド エイブルソン
ピアソンエデュケーション
売り上げランキング: 6542
ピアソンエデュケーション
売り上げランキング: 6542