リストからべき集合を生成する

これがLISPだ! (Information & computing (30))より)
リストを受け取り,そのリストのすべての組み合わせを生成する関数を考える.(飛ばしてよい)問題だったのでスルーしていたけれど,よっしゃやってみようと思って考えること30分.


紙の上で考えたら解法が思いついた.
(nil)からスタートして,リストに含まれるの各リストに新しい要素をconsしたリストをappendしてあげればいいんじゃね?ということで,カキカキ.ある要素をリストに含まれる各リストに追加する関数addtoを補助関数として書く.
最初はバグっていたけれど,落ち着いて書き直したら割と綺麗に書けた.cdr再帰の方がリスト反復より楽に書けるようになってきた.


合計1時間くらいかかったかもしれない.けれど,おかげで自信がついてきたし,少しだけ再帰力がアップしたような気がする.

;; 7.18
(defun powerset (lis)
  (cond ((null lis) (list nil))
	(t (append (addto (car lis) (powerset (cdr lis)))
		   (powerset (cdr lis))))))

(defun addto (a lis)
  (cond ((null lis) nil)
	(t (cons (cons a (car lis)) (addto a (cdr lis))))))

; (powerset '(a b c))
; ((a b c) (a b) (a c) (a) (b c) (b) (c) nil)