問題 2.28

(define (append list1 list2)
  (if (null? list1)
      list2
      (cons (car list1) (append (cdr list1) list2))))

;2.17で目的の機能を果たすものを定義した。
(define (flattern items)
  (append (if (pair? (car items))
              (flattern (car items))
              (cons (car items) null))
          (if (null? (cdr items))
              null
              (if (pair? (cdr items))
                  (flattern (cdr items))
                  (cons (cdr items) null)))))

;でもせっかくだし今回もうひとつ書いた。
(define (fringe x)
  (define (fringe-iter i p)
    (if (null? i) p
        (fringe-iter 
         (cdr i)
         (append p (if (pair? (car i))
                       (fringe-iter (car i) null)
                       (list (car i)))))))
  (fringe-iter x null))

(fringe (list (list 1 (list 2 3) 4 (list 5 6 (list 7 8) 9) 10) (list 11 12) 13))
;-> (1 2 3 4 5 6 7 8 9 10 11 12 13)

;ちょっとちがう風にかいたが、やっている意味は同じ。
;すこし小さくなった?


;↑を書いてる途中でもっといい方法を考えついたので、
;そちらの方法でも作る。

(define (fringe x)
  (define (fringe-iter i p)
    (if (null? i) p
        (if (pair? (car i))
            (fringe-iter (append (car i) (cdr i)) p)
            (fringe-iter (cdr i) (append p (list (car i)))))))
  (fringe-iter x null))

;これでもいいはずだ。


(fringe (list (list 1 (list 2 3) 4 (list 5 6 (list 7 8) 9) 10) (list 11 12) 13))
;-> (1 2 3 4 5 6 7 8 9 10 11 12 13)

;こちらの方が直線的で綺麗。
;しかし、appendは無駄が多すぎる気がする。
;consの情報を直接かきかえられれば、もっと速いとおもうんだけど…