# Exercise 2.41 of SICP

Exercise 2.41: Write a procedure to find all ordered triples of distinct positive integers i, j, and k less than or equal to a given integer n that sum to a given integer s.

(define (filter pred seq)
(cond ((null? seq) '())
((pred (car seq))
(cons (car seq) (filter pred (cdr seq))))
(else
(filter pred (cdr seq)))))

(define (range start end)
(define (iter end seq)
(if (> start end)
seq
(iter (- end 1) (cons end seq))))
(iter end '()))

(define (accumulate fn init-value sequence)
(if (null? sequence)
init-value
(fn (car sequence)
(accumulate fn init-value (cdr sequence)))))

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

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

(define (sum-triples n s)
(define (sum-desired? triple)
(= s (accumulate + 0 triple)))
(define (make-sum-of-triple triple)
(append triple (list (accumulate + 0 triple))))
(map make-sum-of-triple
(filter sum-desired?
(unique-triples n))))

> (sum-triples 5 9)

((4 3 2 9) (5 3 1 9))

> (sum-triples 5 10)

((5 3 2 10) (5 4 1 10))

> (sum-triples 5 11)

((5 4 2 11))

> (sum-triples 5 12)

((5 4 3 12))

> (sum-triples 5 13)

()

> (sum-triples 6 13)

((6 4 3 13) (6 5 2 13))

> (sum-triples 6 10)

((5 3 2 10) (5 4 1 10) (6 3 1 10))

> (sum-triples 6 11)

((5 4 2 11) (6 3 2 11) (6 4 1 11))

> (sum-triples 6 12)

((5 4 3 12) (6 4 2 12) (6 5 1 12))

> (sum-triples 6 13)

((6 4 3 13) (6 5 2 13))