SICPを読む(52) 問題2.29 モビール問題
モビールというとベビーベッドの上にぶら下がっているアレを思い出すんですが、芸術性を極めればこんなにセクシーになるんですね。
僕もセクシーモビールが作りたくなってきてしまった。
問題2.29
イメージ
モビール問題を解く前に、イメージを固めておこう。
- 最軽量のモビール - 図がわかりやすい。
SICPの問題の場合、
これが全体。
| 1 | 2 -L-R--- | | 2 1
モビールと呼ばれる部分は縦棒。右と左がある。
| | L-R
そして、長さのある棒と錘(またはモビール)
2 R--- | 1
によって構成されている。
左右の「棒の長さ * 錘(またはモビール)の全重量」が等しければ、モビールは釣合う。
イメージ重要。
モビールの定義
こんな感じのモビールを解いていくことにする。
(define (make-mobile left right) (list left right)) (define (make-branch length structure) (list length structure)) (define m (make-mobile (make-branch 3 1) (make-branch 1 (make-mobile (make-branch 1 2) (make-branch 2 1)))))
a
色々返す。
(define (left-branch m) (car m)) (define (right-branch m) (cadr m)) (define (branch-length b) (car b)) (define (branch-structure b) (cadr b)) (branch-length (left-branch m)) ; 3 (branch-structure (right-branch m)) ; ((1 2) (2 1))
b
モビールの全重量を返す。
(define (branch-weight b) (let ((s (branch-structure b))) (if (not (pair? s)) s (total-weight s)))) (define (total-weight m) (+ (branch-weight (left-branch m)) (branch-weight (right-branch m)))) (total-weight m) ; 4
cの問題があったので2つの部分に分けた。
c
釣合っているか?
(define (balanced? m) (define (branch-balance b) (* (branch-length b) (branch-weight b))) (if (not (pair? m)) #t (let ((l (left-branch m)) (r (right-branch m))) (and (= (branch-balance l) (branch-balance r)) (balanced? (branch-structure l)) (balanced? (branch-structure r)))))) (balanced? m) ; #t
間違っていたので修正。案外長くなってしまった。
d
consに変えたときの修正範囲。
(define (right-branch m) (cdr m)) (define (branch-structure b) (cdr b))
アクサ部分を変えればいいだけ。
まとめ
最初は全くイメージが湧かなかったが、イメージが掴めれば簡単!