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.
This bears some resemblance to the
prime-sum-pairs
procedure in the "Nested mappings" section and exercise 2.40. This time, however, we want to generate triples of integers, i, j, and k, such that 1 ≤ i < j < k ≤ n and i + j + k = s.We already have a procedure,
unique-pairs
, that will generate all unique ordered pairs of distinct positive integers less than or equal to a given value. We can use this as the basis for building the triples. All we need to do is for each k, such that 3 ≤ k ≤ n, generate the unique pairs of distinct positive integers less than k (using unique-pairs
), add k to each of these pairs to give all of the valid triples for that value of k and then append the results for all values of k together. And the authors have handily provided a procedure, flatmap
, that encapsulates the "map and accumulate with append
" process. Here's the snippet:
(flatmap (lambda (i) (map (lambda (j) (cons i j)) (unique-pairs (- i 1)))) (enumerate-interval 3 n))Now all we need to do is to filter this to those triples whose sum is s and wrap it in a procedure:
(define (triples-equaling s n) (filter (lambda (x) (= (+ (car x) (cadr x) (caddr x)) s)) (flatmap (lambda (i) (map (lambda (j) (cons i j)) (unique-pairs (- i 1)))) (enumerate-interval 3 n))))Let's try it out:
> (triples-equaling 10 10) '((5 3 2) (5 4 1) (6 3 1) (7 2 1)) > (triples-equaling 15 10) '((6 5 4) (7 5 3) (7 6 2) (8 4 3) (8 5 2) (8 6 1) (9 4 2) (9 5 1) (10 3 2) (10 4 1)) > (triples-equaling 6 3) '((3 2 1)) > (triples-equaling 10 5) '((5 3 2) (5 4 1))
No comments:
Post a Comment