理系学生日記

おまえはいつまで学生気分なのか

問題2-41 (2.2.3 Sequences as Conventional Interfaces)

今日は、足してsになるような3つ組をもとめる。
orderedでdistinctって指定なんで、3つ組(i, j, k)はk

; 昨日の
(define (enumerate-interval low high)
  (if (> low high)
      ()
      (cons low (enumerate-interval (+ low 1) high)))) 

; 昨日の
(define (unique-pairs n)
  (flatmap 
   (lambda (i) 
     (map (lambda (j) (list i j))
	  (enumerate-interval 1 (- i 1))))
   (enumerate-interval 1 n)))

(define (unique-triplet n)
  (flatmap 
   (lambda (pair)
     (map (lambda (k)
	    (list (car pair) (cadr pair) k))
	  (enumerate-interval 1 (- (cadr pair) 1))))
   (unique-pairs n)))

unique-triplet はこんな風な出力をかえすよ。

gosh> (unique-triplet 5)
((3 2 1) (4 2 1) (4 3 1) (4 3 2) (5 2 1) (5 3 1) (5 3 2) (5 4 1) (5 4 2) (5 4 3))

そしたら、次はその3つ組が足してsになるかだー。
そのpredicate。

(define (is-sum-equal n t)
  (let ((first (car t))
	(second (cadr t))
	(third (caddr t)))
    (= n (+ first second third))))

あとは昨日と同じだー。

(use srfi-1)

(define (accumulate op initial sequence)
  (if (null? sequence)
      initial
      (op (car sequence)
	  (accumulate op initial (cdr sequence)))))

(define (flatmap proc seq)
  (accumulate append () (map proc seq)))

(define (make-triplet-sum pair)
  (list (car pair) (cadr pair) (caddr pair) (+ (car pair) (cadr pair) (caddr pair))))

(define (sum-n-triplet n s)
  (map make-triplet-sum 
       (filter (lambda (t) (is-sum-equal s t))
	       (unique-triplet n))))

というわけで、10までの数で構成される3つ組で、足して10になるのはこんなtripletです!

gosh> (sum-n-triplet 10 10)
((5 3 2 10) (5 4 1 10) (6 3 1 10) (7 2 1 10))