EoPL reading (106) 2.3 Representation Strategies for Data Types
OSC の合間をぬって練習問題をナニ。電気が無いので紙の上で検討してたりして。
ごにょごにょしてて以下がでっち上がりました。
(add-load-path ".") (load "Fig2.3") (define n-cdr (lambda (n l) (if (= 0 n) ls (n-cdr (- n 1) (cdr l))))) (define list-find-last-position (lambda (n sym los) (cond ((null? los) n) (else (let ((pos (list-index (lambda (sym1) (eqv? sym1 sym)) los))) (if pos (list-find-last-position (+ n pos) sym (n-cdr pos los)) n))))))
あまり自信は無いです。とりあえず n-cdr な試験から。
(test-section "n-cdr") (test* "n is 0" '(a b c) (n-cdr 0 '(a b c)))
n が 0 ならそのまま戻す。
(test* "(n-cdr 1 '(a b c)) return '(b c)" '(b c) (n-cdr 1 '(a b c))) (test* "(n-cdr 2 '(a b c)) return '(c)" '(c) (n-cdr 2 '(a b c))) (test* "(n-cdr 3 '(a b c)) return '()" '() (n-cdr 3 '(a b c)))
これ、n と (length l) のナニは略で良いのかどうなのか。こんなモノとして本体の試験に着手。
って、これ存在しない場合、0 が戻るんですがどうしたものやら。pos が偽で n が 0 なら偽を戻すか。
(let ((pos (list-index (lambda (sym1) (eqv? sym1 sym)) los))) (if pos (list-find-last-position (+ n pos) sym (n-cdr pos los)) (if (= 0 n) #f n)))))))
で、見つからないケイスの試験が以下。
(test-section "list-find-last-position") (test* "(list-find-last-pos 0 'z '(a b c)) -- not found" #f (list-find-last-position 0 'z '(a b c)))
試験失敗。よく見たら list-find-position でなくて list-index 使ってますな。修正。
(define list-find-last-position (lambda (n sym los) (cond ((null? los) n) (else (let ((pos (list-find-position sym los))) (if pos (list-find-last-position (+ n pos) sym (n-cdr pos los)) (if (= 0 n) #f n)))))))
で、再試したらパスとの事。試験追加。
(test* "(list-find-last-pos 0 'a '(a b c)) returns 0" 0 (list-find-last-position 0 'a '(a b c)))
で、試験起動したらループした。プラいちしないとダメな事に気づく。ってか上記実装は全然ダメって事な模様。どうしたものやら。
で、時間けっこうギリですが以下がでっち上がる。
(define list-find-last-position (lambda (n sym los) (let ((pos (list-find-position sym los))) (if (not pos) pos (let f ((n (+ n pos)) (sym sym) (los (n-cdr (+ pos 1) los))) (let ((pos (list-find-position sym los))) (if pos (f (+ n pos) sym (n-cdr (+ pos 1) los)) n)))))))
なんかごちゃごちゃしてるなぁ。上記の試験にはパスしている模様。でテキストにある以下の例を試してみたんですが
(test* "(list-find-last-pos 0 'a '(c a b a c a d e)) returns 5" 5 (list-find-last-position 0 'a '(c a b a c a d e)))
3 が戻る、と叱られる。
test (list-find-last-pos 0 'a '(c a b a c a d e)) returns 5: expects 5 => got 3
とほほ。原因は分かったんですがどうすりゃいいんでしょ。無理矢理ですがこうか。
(f (+ n (+ pos 1)) sym (n-cdr (+ pos 1) los))
結局 pos に 1 加えた値をナニしないと駄目なのか。とほほ。
一応以下な試験も追加。
(test* "(list-find-last-pos 0 'a '(c a b a c a d a)) returns 7" 7 (list-find-last-position 0 'a '(c a b a c a d a)))
パスしてます。一応できた、ってコトで良いのかどうか。