{[ promptMessage ]}

Bookmark it

{[ promptMessage ]}

proj 2 - Nested Mappings We can extend the sequence...

Info iconThis preview shows pages 1–3. Sign up to view the full content.

View Full Document Right Arrow Icon
Nested Mappings We can extend the sequence paradigm to include many computations that are commonly expressed using nested loops. 18 Consider this problem: Given a positive integer n , find all ordered pairs of distinct positive integers i and j , where 1< j < i < n , such that i + j is prime. For example, if n is 6, then the pairs are the following: A natural way to organize this computation is to generate the sequence of all ordered pairs of positive integers less than or equal to n , filter to select those pairs whose sum is prime, and then, for each pair ( i , j ) that passes through the filter, produce the triple ( i , j , i + j ). Here is a way to generate the sequence of pairs: For each integer i < n , enumerate the integers j < i , and for each such i and j generate the pair ( i , j ). In terms of sequence operations, we map along the sequence (enumerate-interval 1 n) . For each i in this sequence, we map along the sequence (enumerate-interval 1 (- i 1)) . For each j in this latter sequence, we generate the pair (list i j) . This gives us a sequence of pairs for each i . Combining all the sequences for all the i (by accumulating with append ) produces the required sequence of pairs: 19 (accumulate append nil (map (lambda (i) (map (lambda (j) (list i j)) (enumerate-interval 1 (- i 1)))) (enumerate-interval 1 n))) The combination of mapping and accumulating with append is so common in this sort of program that we will isolate it as a separate procedure: (define (flatmap proc seq) (accumulate append nil (map proc seq))) Now filter this sequence of pairs to find those whose sum is prime. The filter predicate is called for each element of the sequence; its argument is a pair and it must extract the integers from the pair. Thus, the predicate to apply to each element in the sequence is (define (prime-sum? pair) (prime? (+ (car pair) (cadr pair)))) Finally, generate the sequence of results by mapping over the filtered pairs using the following procedure, which constructs a triple consisting of the two elements of the pair along with their sum: (define (make-pair-sum pair) (list (car pair) (cadr pair) (+ (car pair) (cadr pair)))) Combining all these steps yields the complete procedure: (define (prime-sum-pairs n) (map make-pair-sum (filter prime-sum? (flatmap (lambda (i) (map (lambda (j) (list i j))
Background image of page 1

Info iconThis preview has intentionally blurred sections. Sign up to view the full version.

View Full Document Right Arrow Icon
(enumerate-interval 1 (- i 1)))) (enumerate-interval 1 n))))) Nested mappings are also useful for sequences other than those that enumerate intervals. Suppose we wish to generate all the permutations of a set S ; that is, all the ways of ordering the items in the set. For instance, the permutations of {1,2,3} are {1,2,3}, { 1,3,2}, {2,1,3}, { 2,3,1}, { 3,1,2}, and { 3,2,1}. Here is a plan for generating the permutations of S : For each item x in S , recursively generate the sequence of permutations of S - x , 20 and adjoin x to the front of each one. This yields, for each x in S , the sequence of permutations of S that begin with x . Combining these sequences for all x gives all the permutations of S : 21 (define (permutations s) (if (null? s) ; empty set?
Background image of page 2
Image of page 3
This is the end of the preview. Sign up to access the rest of the document.

{[ snackBarMessage ]}