関数型言語の勉強にSICPを読もう - (14) 2章 - データによる抽象の構築(70-73ページ)

2.2.3公認インターフェースとしての並びのつづき

問題2.37

一旦パス。
余裕があったらここに戻ろう。
mapの使い方の勉強になりそうな気がする。

問題2.38

上から順に

  • 3/2
  • 1/6
  • (1 (2 (3)))→間違い(1 (2 (3 ())))
  • (3 (2 (1)))→間違い(((() 1) 2) 3)

満たすべき性質は・・・演算の順序に結果が依存しないこと。
→答えを見たら結合則と書いてあった。

計算の順序を変えても同じ結果がでる場合に、その計算は結合法則を満たすと言う

問題2.39

(define (reverse sequence)
  (fold-right (lambda (x y) (append y (list x))) nil sequence))
(define (reverse-2 sequence)
  (fold-left (lambda (x y) (cons y x)) nil sequence))

fold-right, fold-leftってどれくらい重要なんだろうか。
記憶に残らない気がする。

写像入れ子

(define (enumrate-interval l h)
  (if (> l h)
       '()
       (cons l (enumrate-interval (+ l 1) h))))

(accumulate append
            '()
            (map (lambda (i)
                   (map (lambda (j) (list i j))
                        (enumrate-interval 1 (- i 1))))
                   (enumrate-interval 1 5)))
gosh> ((2 1) (3 1) (3 2) (4 1) (4 2) (4 3) (5 1) (5 2) (5 3) (5 4))

この(i j)の組み合わせを作る際の説明文がとても分かりづらいのだが、コードを打ち込んで実行してみるとよく分かる。
(1 2 3 4 5)というリストの全ての要素に対して、その要素より1小さい数を最大として enumrate-interval してlistを作っているのだ。
自分で書いていて全然説明になっていない気がするけどここまでは理解できたので良しとする。
(map (lambdaが入れ子になっても自然に受け入れられるようになってきたのは進歩したのかもしれない。

問題2.40

頭の筋肉がギシギシと音を立てています。

まず enumrate-interval の動作確認

(enumrate-interval 1 5)
gosh> (1 2 3 4 5)

自分が何をやっているのか分からなくなってきた。
これでよいのかな?

(define (uniq-pair n)
  (accumulate append
              '()
              (map (lambda (i)
                     (map (lambda (j) (list i j))
                          (enumrate-interval 1 (- i 1))))
                   (enumrate-interval 1 n))))

(uniq-pair 6)

(define (prime-sum? pair)
  (prime? (+ (car pair) (cadr pair))))
(define (make-pair-sum pair)
  (list (car pair) (cadr pair) (+ (car pair) (cadr pair))))
(define (prime-sum-pairs s)
  (map make-pair-sum
       (filter prime-sum?
               (uniq-pair s))))
(prime-sum-pairs 3)

問題2.41

(i j k)の組み合わせを作って filter でしぼる。
それで(i j k (+ i j k))のリストを作るという流れでよいと思う。

(uniq-pair)を更に一つ入れ子にすれば(i j k)が取り出せそうだと考える。
でも頭が「がーっ」となって知恵熱が出たので答えを見た。

(define (unique-triples n)
  (flatmap (lambda (i)
             (flatmap (lambda (j)
                        (map (lambda (k) (list i j k))
                             (enumerate-interval 1 (- j 1))))
                      (enumerate-interval 1 (- i 1))))
           (enumerate-interval 1 n)))

なるほど。これは後で頭を冷やしてからもう一度やろう。


※「SICPを読もう」の目次はこちら


計算機プログラムの構造と解釈
Gerald Jay Sussman Julie Sussman Harold Abelson 和田 英一
ピアソンエデュケーション (2000/02)
売り上げランキング: 56,404