第13回SICP勉強会
先週UPを忘れていた
問題
問題2.24
;; 問題2.24 ;; これは絵を書けばいいのかな (list 1 (list 2 (list 3 4))) ;; gosh> (1 (2 (3 4))) ;; 箱の絵 ;; http://f.hatena.ne.jp/rindai87/20120324235452( ;; 木の絵 ;; http://f.hatena.ne.jp/rindai87/20120324235453 ;; http://wqzhang.wordpress.com/2009/06/19/sicp-exercise-2-24/
問題2.25
;; 問題2.25 (1 3 (5 7) 9) (define x (list 1 3 (list 5 7) 9)) (car (cdr (car (cdr (cdr x))))) ;; gosh> 7 ;; cdr => cdr => car => cdr => car ((7)) (define x (list (list 7))) (car (car x)) ;; gosh> 7 ;; car => car (caar x) ;; gosh> 7 (1 (2 (3 (4 (5 (6 7)))))) (define x (list 1 (list 2 (list 3 (list 4 (list 5 (list 6 7))))))) (car (cdr (car (cdr (car (cdr (car (cdr (car (cdr (car (cdr x)))))))))))) ;; gosh> 7 ;; cdr => car ;; => cdr => car ;; => cdr => car ;; => cdr => car ;; => cdr => car ;; => cdr => car
問題2.26
;; 問題2.26 (define x (list 1 2 3)) (define y (list 4 5 6)) (append x y) ;; gosh> (1 2 3 4 5 6) (cons x y) ;; gosh> ((1 2 3) 4 5 6) (list x y) ;; gosh> ((1 2 3) (4 5 6))
問題2.27
;; 問題2.27 (define x (list (list 1 2) (list 3 4))) ;; reverseはgauche組み込みであるけど、念のために (define (reverse-new items) (define (reverse-iter rev-items items) (if (null? items) rev-items (reverse-iter (cons (car items) rev-items) (cdr items)))) (reverse-iter () items)) (reverse-new (list 1 2 3 4)) ;; 最初に思いついた回答 ;; 対なら(cdr, car)でくっつけて再帰的にたどっていく (define (deep-reverse items) (if (pair? items) (append (deep-reverse (cdr items)) (list (deep-reverse (car items)))) items)) (deep-reverse x) ;; mapを使う ;; 葉まで分解し、再構築してreverseしながらくっつけていく (define (deep-reverse items) (if (not (pair? items)) items (reverse (map deep-reverse items)))) x ;; gosh> ((1 2) (3 4)) (reverse x) ;; gosh> ((3 4) (1 2)) (deep-reverse x) ;; gosh> ((4 3) (2 1))
問題2.28
;; 問題2.28 (define x (list (list 1 2) (list 3 4))) ;; count-leavesを流用する (define (fringe items) (cond [(null? items) items] [(not (pair? items)) (list items)] [else (append (fringe (car items)) (fringe (cdr items)))])) (fringe x) ;; gosh> (1 2 3 4) (fringe (list (list 1 2) (list (list 3 4) 5 (list 6 7)) (list 8 9))) ;; gosh> (1 2 3 4 5 6 7 8 9)
問題2.29
;; 問題2.29 ;; 2進モービルを二つの枝からできている ;; 合成データで表現 (define (make-mobile left right) (list left right)) ;; 一つの枝はlength(数でなければならない)と, ;; 数か別のモービルであるstructureで ;; 構成する (define (make-branch length structure) (list length structure)) ;; a. ;; モービルの枝を返す手続き (define (left-branch mobile) (car mobile)) (define (right-branch mobile) (car (cdr mobile))) ;; 枝の部品を返す手続き (define (branch-length branch) (car branch)) (define (branch-structure branch) (car (cdr branch))) ;; aの確認 (define mobile1 (make-mobile (make-branch 1 2) (make-branch 3 4))) (define mobile2 (make-mobile (make-branch 6 2) (make-branch 1 (make-mobile (make-branch 2 4) (make-branch 1 8))))) (print mobile1) ;; gosh> ((1 2) (3 4)) (left-branch mobile1) ;; gosh> (1 2) (right-branch mobile1) ;; gosh> (3 4) (branch-length (left-branch mobile1)) ;; gosh> 1 (branch-structure (left-branch mobile1)) ;; gosh> 2 ;; b. ;; aで定義した選択肢を使って, モービルの全重量を ;; 返す手続きtotal-weightを定義する ;; mobileを与えて全重量を求めるtotal-weight (define (total-weight mobile) (+ (branch-weight (left-branch mobile)) (branch-weight (right-branch mobile)))) (define (branch-weight branch) (if (number? (branch-structure branch)) (branch-structure branch) (total-weight (branch-structure branch)))) (display mobile1) ;; gosh> ((1 2) (3 4)) (total-weight mobile1) ;; gosh> 6 ;; 2 + 4 = 6 (display mobile2) ;; gosh> ((6 2) (1 ((2 4) (1 8)))) (total-weight mobile2) ;; gosh> 14 ;; 2 + 4 + 8 = 14 ;; c. ;; 二進モービルが釣り合っているか釣り合ってるかどうかのテスト ;; 回転力:長さ×重さ ;; 方針 ;; 最上段で左右の枝が釣り合っているか調べる ;; 釣り合っていたら、再帰的に双方の枝が釣り合っているか調べる ;; 釣り合っていない枝が見つかったら終了 (define (balanced? mobile) (let ((left-moment (* (branch-length (left-branch mobile)) (branch-weight (left-branch mobile)))) (right-moment (* (branch-length (right-branch mobile)) (branch-weight (right-branch mobile))))) (if (= left-moment right-moment) (and (balanced-branch? (left-branch mobile)) (balanced-branch? (right-branch mobile))) #f))) (define (balanced-branch? branch) (if (number? (branch-structure branch)) #t (balanced? (branch-structure branch)))) ;; 検証1.バランスがとれている (define mobile3 (make-mobile (make-branch 1 2) (make-branch 1 2))) (balanced? mobile3) ;; gosh> #t ;; 検証2. ちょっと複雑だがバランスがとれている (define mobile4 (make-mobile (make-branch 1 (make-mobile (make-branch 2 3) (make-branch 3 2))) (make-branch 1 (make-mobile (make-branch 3 2) (make-branch 2 3))))) (balanced? mobile4) ;; 検証3. ちょっと複雑だがバランスがとれていない (define mobile5 (make-mobile (make-branch 3 (make-mobile (make-branch 6 3) (make-branch 3 6))) (make-branch 7 7))) (balanced? mobile5) ;; gosh> #f ;; 検証4. 最上段はバランスがとれている。枝にぶら下がっているモービルでバランスがとれていない (define mobile6 (make-mobile (make-branch 5 (make-mobile (make-branch 3 2) (make-branch 3 4))) (make-branch 5 6))) (balanced? mobile6) ;; d. ;; make-mobile, make-branchの実装が変わった時の対応 (define (make-mobile left right) (cons left right)) (define (make-branch length structure) (cons length structure)) (define mobile3 (make-mobile (make-branch 1 2) (make-branch 1 2))) (define mobile4 (make-mobile (make-branch 1 (make-mobile (make-branch 2 3) (make-branch 3 2))) (make-branch 1 (make-mobile (make-branch 3 2) (make-branch 2 3))))) ;; 検証用 (display mobile3) (left-branch mobile3) (right-branch mobile3) (branch-length (left-branch mobile3)) (branch-weight (left-branch mobile3)) (branch-length (right-branch mobile3)) (branch-weight (right-branch mobile3)) (total-weight mobile3) (balanced? mobile3) (display mobile4) (left-branch mobile4) (right-branch mobile4) (branch-length (left-branch mobile4)) (branch-weight (left-branch mobile4)) (branch-length (right-branch mobile4)) (branch-weight (right-branch mobile4)) (total-weight mobile4) (balanced? mobile4) ;; consとlistに対してcarとcdrを適用した時の結果を確認 (car (cons (cons 1 2) (cons 1 2))) (car (list (list 1 2) (list 1 2))) (cdr (cons (cons 1 2) (cons 1 2))) (cdr (list (list 1 2) (list 1 2))) ;; P55図2.2とP56図2.4を見ればconsとlistの ;; データ構造の違いが理解できる ;; cadrを使っている手続きを修正する ;; right-branch, branch-structure (define (right-branch mobile) (cdr mobile)) (define (branch-structure branch) (cdr branch)) ;; 検証用 (display mobile3) (left-branch mobile3) (right-branch mobile3) (branch-length (left-branch mobile3)) (branch-weight (left-branch mobile3)) (branch-length (right-branch mobile3)) (branch-weight (right-branch mobile3)) (total-weight mobile3) (balanced? mobile3) (display mobile4) (left-branch mobile4) (right-branch mobile4) (branch-length (left-branch mobile4)) (branch-weight (left-branch mobile4)) (branch-length (right-branch mobile4)) (branch-weight (right-branch mobile4)) (total-weight mobile4) (balanced? mobile4)
問題2.30
;; 問題2.30 ;; 再帰を利用したもの (define (square-tree tree) (define nil '()) (cond [(null? tree) nil] [(not (pair? tree)) (* tree tree)] [else (cons (square-tree (car tree)) (square-tree (cdr tree)))])) (square-tree (list 1 (list 2 (list 3 4) 5) (list 6 7))) ;; gosh> (1 (4 (9 16) 25) (36 49)) ;; mapを利用したもの (define (square-tree tree) (map (lambda (sub-tree) (if (pair? sub-tree) (square-tree sub-tree) (* sub-tree sub-tree))) tree)) (square-tree (list 1 (list 2 (list 3 4) 5) (list 6 7))) ;; gosh> (1 (4 (9 16) 25) (36 49))
問題2.31
;; 問題2.31 (define (tree-map proc tree) (map (lambda (sub-tree) (if (pair? sub-tree) (tree-map proc sub-tree) (proc sub-tree))) tree)) (define (square x) (* x x)) (define (square-tree tree) (tree-map square tree)) (square-tree (list 1 (list 2 (list 3 4) 5) (list 6 7))) ;; gosh> (1 (4 (9 16) 25) (36 49))
問題2.32
;; 問題2.32 ;; 集合の全ての部分集合の集合を表現する ;; 冪集合の話 ;; 冪集合Xは集合Xの全ての部分集合の集合 ;; => Xのある要素を抜き出した集合の部分集合と、各部分集合にXを加えた和集合 ;; => subsets内のrestが先頭要素を取り除いたもの ;; => そこに取り除いた先頭要素を加えればよい?? ;; (subset (cdr (1 2 3))) ;; => (subset (2 3)) だから 1を加えるような処理 ;; => (append (map <1を加えるような手続き> rest)) ;; => 空欄部分は(append (map <(lambda (x) (cons (car s) x))> rest)) (define nil '()) (define (subsets s) (if (null? s) (list nil) (let ((rest (subsets (cdr s)))) (append rest (map (lambda (x) (cons (car s) x)) rest))))) (print (subsets (list 1 2 3))) ;; gosh> (() (3) (2) (2 3) (1) (1 3) (1 2) (1 2 3)) ;; #<undef> (use slib) (require 'trace) (trace subsets) (print (subsets (list 1 2 3))) ;; gosh> CALL subsets (1 2 3) ;; CALL subsets (2 3) ;; CALL subsets (3) ;; CALL subsets () ;; RETN subsets (()) ;; RETN subsets (() (3)) ;; RETN subsets (() (3) (2) (2 3)) ;; RETN subsets (() (...) (...) (...) (1) (1 ...) (1 2) (1 2 3)) ;; http://d.hatena.ne.jp/awacio/20100512/1273670118
所感
発表頑張りましたが、まだまだ修行が足りませんでした。