読者です 読者をやめる 読者になる 読者になる

Arantium Maestum

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

SICPの勉強 問題2.30~32

Clojure SICP

2.30

木構造のデータ(nestしたリスト)の全ての葉ノードを二乗する関数:

(defn square-tree [tree]
  (cond
    (empty? tree)
    ()
    
    (seq? (first tree))
    (cons (square-tree (first tree))
          (square-tree (rest tree)))
    
    :else
    (cons (sq (first tree))
          (square-tree (rest tree)))))

2.31

木構造のデータ(nestしたリスト)の全ての葉ノードに任意の関数を適用する関数:

(defn tree-map [f tree]
  (cond 
    (empty? tree)
    ()
    
    (seq? (first tree))
    (cons (tree-map f (first tree))
          (tree-map f (rest tree)))
    
    :else
    (cons (f (first tree))
          (tree-map f (rest tree)))))

普通のmapを使って書き直すなら:

(defn tree-map-m [f tree]
  (if (not (seq? tree))
    (f tree)
    (map #(tree-map-m f %) tree)))

例によってヴェクタは存在しないものとする。まあ、リストと数字しか存在しないという過程はSICP的にはそんなに荒唐無稽な仮定ではないと思う。

2.32

リストの要素から作り得る全ての部分集合を返す関数:

(defn subsets [s]
  (if (empty? s)
    ()
    (let [current-element (first s)
          subsets-of-rest (subsets (rest s))]
      (concat subsets-of-rest 
              (map (fn [subset] 
                     (cons current-element subset)) 
                   subsets-of-rest)))))