Arantium Maestum

プログラミング、囲碁、読書の話題

SICPの勉強 問題2.27~28

2.27

リストの要素を逆順にするだけでなく、そのリストに含まれる全てのリストも同時に逆にする関数:

(defn deep-reverse [x]
  (if (not (seq? x))
    x
    (loop [items  x
           result ()]
      (if (empty? items)
        result
        (recur (rest items)
               (cons (deep-reverse (first items))
                     result))))))

Dynamic typing万歳、と言いたくなるようなゆる〜い実装。あと、seq?だとリストやconsでできた遅延リストは大丈夫だがvectorはダメ。

2.28

nested-listを完全にflatten化する関数:

(defn fringe-r [tree result]
  (cond
    (empty? tree)
    result
    
    (seq? (first tree))
    (fringe-r (rest tree)
              (fringe-r (first tree) result))
    
    :else
    (fringe-r (rest tree)
              (cons (first tree) result))))

(defn fringe [tree]
  (reverse (fringe-r tree ())))

とりあえず再帰とconsだと逆さまに結果が出てくるので、一旦別関数で逆順の結果を出させてreverseで直している。