同じ文字をまとめる
common lispでの実装を通して,schemeとの違いが書かれている.
このページに
(pack '(a a a a b c c a a d e e e e)) ((A A A A) (B) (C C) (A A) (D) (E E E E))
と結果が返ってくるような関数packが載っていたので,schemeでやってみた.
(define (pack lis) (pack-first lis)) (define (pack-first lis) (if (null? lis) '() (let ((x (car lis)) (y (cadr lis))) (if (equal? x y) (pack-core (cddr lis) (list x y) '()) (pack-core (cdr lis) (list x) '()))))) (define (pack-core lis tmp-lis result) (if (null? lis) (append result (list tmp-lis)) (let ((x (car lis)) (y (car tmp-lis))) (if (equal? x y) (pack-core (cdr lis) (append tmp-lis (list y)) result) (pack-core (cdr lis) (list x) (append result (list tmp-lis)))))))
(pack '(a a a d b b c c a a)) ;=> ((a a a) (d) (b b) (c c) (a a))
ひとつの関数でできるんだけれど,今回はあえてばらした.なぜかというと,うえのページに書いてあったんだけど,
traceで局所関数を追うのは難しいんで、局所関数はデバッグ向けじゃない
まさにSICPで苦しんだのがこれで,letで内部的に定義したものにバグがあると,見つけるのがかなりきつい.
なので,今回は一応ばらして書いた.
しかし...もうちょっとまとめられるだろ.pack-firstとpack-coreはtmp-lisが空の場合とそうでない場合なだけの違いなのだから..