#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 move the definition of the recursor function fmap2lcm-r inside the main ; function. This means that the recursor has access to the original X and Y ; lists, so they do not have to be passed down the recursion. (define fmap2lcm (lambda (fn X Y) (define fmap2lcm-r (lambda (fn X-cur Y-cur) (cond ; both lists done at same time - have reached lcm [ (and (null? X-cur) (null? Y-cur)) '() ] ; X runs out first, recycle [ (null? X-cur) (fmap2lcm-r fn X Y-cur) ] ; Y runs out first, recycle [ (null? Y-cur) (fmap2lcm-r fn X-cur Y) ] ; process first of both and recurse. [ else (cons (fn (first X-cur) (first Y-cur)) (fmap2lcm-r fn (rest X-cur) (rest Y-cur) )) ] ))) ; handle special boundary case of empty input lists (if (or (null? X) (null? Y)) '() (fmap2lcm-r fn X Y)) ))