今日は、足して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))