SICP問題2.41
与えられた整数nに対し、nより小さいか等しい相異なる正の整数i, j, kの順序づけられた三つの組で、和が与えられた整数 s になるものを全て見つる手続き
まず 1 <= i < j < k <= n を満たすi, j, kの全ての組合せを作る手続き unique-list の定義
(define (unique-list n) (flatmap (lambda (i) (map (lambda (j) (append (list i) j)) (flatmap (lambda (j) (map (lambda (k) (list j k)) (enumerate-interval 1 (- j 1)))) (enumerate-interval 1 (- i 1))))) (enumerate-interval 1 n)))
整数sとi, j, kの和が等しいかをテストするsum-equal-s?の定義
(define (sum-equal-s? lists s) (= (accumulate + 0 lists) s))
リストを作る手続きmake-sum-list
(define (make-sum-list lists) (append lists (list (accumulate + 0 lists))))
問題の手続きsum-list-equal-s
(define (sum-list-equal-s n s) (map make-sum-list (filter (lambda (x) (sum-equal-s? x s)) (unique-list n))))
と書いたんだけど、Webで人の答えを見てるとダメダメですね。
教科書のソース見て、無理やりflatmapを入れて
flatmap -> map -> flatmap -> map
とかやってたんだけど、単純に
flatmap -> flatmap -> map で良いんですよね。ということで、uniq-listをちょっと修正。
(define (unique-list 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)))
他の部分は、そのうち気が向いたら。(^_^;