EoPL reading (4) 1.2.4 Exercises
このあたりはなるべく機械的にイキたいのですが。
Exercise 1.15-5
試験は以下
(use gauche.test) (add-load-path ".") (load "exist?") (test-start "1.15-5") (test-section "test-exist?") (test* "(exists? number? '(a b c 3 e))" #t (exists? number? '(a b c 3 e))) (test* "(exists? number? '(a b c d e))" #f (exists? number? '(a b c d e))) (test-end)
これは number? が真な時点で終了すれば良い。ので以下でしょうか。
(define (exists? pred lst) (if (null? lst) #f (if (pred (car lst)) #t (exists? pred (cdr lst)))) )
試験にはパスしてます。
Exercise 1.15-6
げ。vector が出てきた。pred が真になる最初のインデクスを戻せば良い、のかな。とりあえず試験を書いてみる。
(use gauche.test) (add-load-path ".") (load "vector-index") (test-start "1.15-6") (test-section "test-vector-index") (test* "(vector-index (lambda (x) (eqv? x 'c)) '#(a b c d))" 2 (vector-index (lambda (x) (eqv? x 'c)) '#(a b c d))) (test* "(vector-ref '#(a b c) (vector-index (lambda (x) (eqv? x 'b)) '#(a b c)))" 'b (vector-ref '#(a b c) (vector-index (lambda (x) (eqv? x 'b)) '#(a b c)))) (test-end)
微妙ですが試験には失敗している模様。本体を書いてみる。最初に pred が真なインデクスを戻せば良いのか。一発書きだとどうすりゃ良いのやら。
(define (vector-index pred v) (define (inner-vector-index i) (if (> i (vector-length v)) #f (if (pred (vector-ref v i)) i (inner-vector-index (+ i 1))))) (inner-vector-index 0) )
試験が足らんな。見つからない場合、だけで良いのか。
(test* "(vector-index (lambda (x) (eqv? x 'e)) '#(a b c d))" #f (vector-index (lambda (x) (eqv? x 'e)) '#(a b c d)))
で、インデクスな比較演算が微妙なコトが判明。正しくは以下な模様
(if (>= i (vector-length v))
Exercise 1.15-7
酔っぱらってきた。試験を以下に
(use gauche.test) (add-load-path ".") (load "list-set") (test-start "1.15-7") (test-section "test-list-set") (test* "(list-set '(a b c d) 2 '(1 2))" '(a b (1 2) d) (list-set '(a b c d) 2 '(1 2))) (test* "(list-ref (list-set '(a b c d) 3 '(1 5 10)) 3)" '(1 5 10) (list-ref (list-set '(a b c d) 3 '(1 5 10)) 3)) (test-end)
微妙な実装が以下
(define (list-set lst n x) (define (inner-list-set l i) (if (= i n) (cons x (cdr l)) (cons (car l) (inner-list-set (cdr l) (+ i 1)))) ) (inner-list-set lst 0) )
中の define でなんとかしてるあたり、微妙な気がしてるんですが。あと n が lst のインデクスを越えてたソレな対応が無いのはどうなのか。