もうひとつのScheme入門 7.繰り返し の練習問題2 末尾再帰

たまに問題によっては少し作り方が違う感じになってる。

プログラムを作るときに、どんな風に実行させるか考えてテスト用のソースコードを書くと実装のミスを減らせるからいいかも。多分手法としてはテストファーストを実践したと思う。特に問題3はテストを先に書いておいたから、引数をちゃんと文字列にしないといけないことに気づけた。

また、問題1の (if (null? lst) の部分は (if (null? (cdr lst)) にすると、 (my-reverse-tail '()) が実行できないことにもテストで気づけた。学校でテストファーストの手法を教えてもらってたら、もうちょっとが楽になったんじゃないかと思ったりする。

もうひとつのScheme入門 7.繰り返し の練習問題2 末尾再帰

問題1

(define (my-reverse-tail lst)
(my-reverse-rec lst))

(define (my-reverse-rec lst)
(if (null? lst)
lst
(append (my-reverse-rec (cdr lst)) (list (car lst)))))

(define (my-reverse-tail lst)
  (my-reverse-rec lst '()))

(define (my-reverse-rec lst result-lst)
  (if (null? lst)
    result-lst
    (my-reverse-rec (cdr lst) (cons (car lst) result-lst))))

実行結果

(my-reverse-tail '(1 2 3 4 5))
(5 4 3 2 1)

(my-reverse-tail '())
()

問題2

(define (my-sum-tail lst)
  (my-sum-rec lst 0))

(define (my-sum-rec lst sum)
  (if (null? lst)
    sum
    (my-sum-rec (cdr lst) (+ sum (car lst)))))

実行結果

(my-sum-tail '(5 10 15 20))
50

(my-sum-tail '())
0

問題3

(define (my-string-to-integer str)
  (my-string-to-integer-rec (string->list str) 0))

(define (my-string-to-integer-rec str-lst result-num)
  (if (null? str-lst)
    result-num
    (my-string-to-integer-rec (cdr str-lst)
			      (+ (- (char->integer (car str-lst)) 48)
				 (* result-num 10)))))

実行結果

(my-string-to-integer "1234567890")
1234567890

(my-string-to-integer "")
0