#lang racket ; If X = (x_0 x_1 ... x_n) and Y = (y_0 y_1 ... y_m) then ; (fmap2lcm fn X Y) ; is the list (r_0 r_1 ... r_l) where where the element r_i ; in position i is (fn x_(i mod n) y_(i mod m)) ; and l = lcm(m, n) where lcm - least common multiple. ; ; In other words the map is performed by reusing the lists X and Y until ; they both end at the same time. ; Example: (fmap2lcm list '(1 2) '(3 4 5)) is ; ((1 3) (2 4) (1 5) (2 3) (1 4) (2 5)) ; Cleanup: ; we make a final cleanup by observing that we can have just one recursive ; call point if we reset the list that ran out. Then we can eliminate the ; multiple cases in the cond and restore the if. (define fmap2lcm (lambda (fn X Y) ; recursor (define fmap2lcm-r (lambda (fn X-cur Y-cur) ( let ( ; wrap X-cur and Y-cur if they are finished [ X-r (if (null? X-cur) X X-cur) ] [ Y-r (if (null? Y-cur) Y Y-cur) ] ) (if (and (null? X-cur) (null? Y-cur)) ; when both empty have hit the lcm '() ; otherwise process one more element and recurse (cons (fn (first X-r) (first Y-r)) (fmap2lcm-r fn (rest X-r) (rest Y-r) )) ) ))) ; end of fmap2lcm-r ; handle special boundary case of empty input lists (if (or (null? X) (null? Y)) '() (fmap2lcm-r fn X Y)) ))