SICPを読む(51) 問題 2.24 - 2.28 リスト巡り
SICPネタを書くとアクセス数が激減することが判明。ブログで読者を逃すならSICPを読もう。
問題 2.24
まずは、括弧表現で、書いてみる。
(1 (2 (3 4)))
評価してみる。ドキドキ。
(list 1 (list 2 (list 3 4))) ; (1 (2 (3 4)))
あってた。
よく見ると、
(list 1 (list 2 (list 3 4))) ; vimで :.s/list //g する。 (1 (2 (3 4)))
括弧表現では(list ...)を()に置き換えただけであることがわかった。
AAで木表現を書くのは辛そうなので、ポインタ表現で。
[ | ] - [ |/] | | 1 [ | ] - [ |/] | | 2 [ | ] - [ |/] | | 3 4
(list 3 4)から作るとわかりやすかった。
count-nils
count-leavesの逆を作ってみた。nilの数を数える。
(define (count-nils x) (cond ((null? x) 1) ((not (pair? x)) 0) (else (+ (count-nils (car x)) (count-nils (cdr x))))))
ホントに逆にしただけ(笑
「リストの数 = nilの数」になるので、リストがいくつあるのかわかる。
nilは無を表すので、無が複数あるというnilsはなんかおかしい。
問題 2.25
リストをcar,cdrで巡ろう。
(car (cdr (car (cdr (cdr `(1 3 (5 7) 9)))))) (car (car `((7)))) (car (cdr (car (cdr (car (cdr (car (cdr (car (cdr (car (cdr `(1 (2 (3 (4 (5 (6 7))))))))))))))))))
問題 2.26
全然迷わず、解けた。
(define x (list 1 2 3)) (define y (list 4 5 6)) (append x y) ; (1 2 3 4 5 6) (cons x y) ; ((1 2 3) 4 5 6) (list x y) ; ((1 2 3) (4 5 6))
完全理解。
問題 2.27
要素を全て逆順にする。
(deep-reverse `((1 2 3) (4 5 6))) ; ((6 5 4) (3 2 1))
を作る。
できたぁぁぁぁ!!嬉しい!!激しく嬉しい!!
(define (deep-reverse items) (define (iter i a) (if (null? i) a (iter (cdr i) (cons (if (list? (car i)) (iter (car i) `()) (car i)) a)))) (iter items `())) (deep-reverse `((1 2 3) (4 5 6))) ; ((6 5 4) (3 2 1))
値がリストであれば、cons内で、もう一回iterする。
list?を使ってるのは内緒。
数学以外は解けそうな気分
解答例いろいろ
(list? (cons 1 2)) ; #f (list? (list 1 2)) ; #t (pair? (cons 1 2)) ; #t (pair? (list 1 2)) ; #t
-
-
- 一個先を見れば良いだけなので、pair?で充分対応できる。
-
- ex-2.27 | SICP | OpenSource Web
- セクシー過ぎるよ!!グレイトジョブ!!
- mapという発想はなかった。
- 展開すると・・・。
(deep-reverse `((1 2) (3 4))) (reverse (map reverse `((1 2) (3 4)))) (reverse (list (reverse `(1 2)) (reverse `(3 4))))
map再帰すげ〜〜〜〜〜〜〜!!
問題 2.28
リストをフラットに並び替える。
appendを使ってみた。
(define (fringe tree) (cond ((null? tree) `()) ((not (pair? tree)) (list tree)) (else (append (fringe (car tree)) (fringe (cdr tree)))))) (fringe `((1 (2 3)) ((4 5) 6))) ; (1 2 3 4 5 6)
かなり苦戦したけど、もっと良い方法がある気がする。