#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: ; Since the agorithm is more a sequence of guarded commands instead of a ; decision tree, we replace the nested if-statements with a cond-statement ; (define fmap2lcm-r (lambda (fn X-cur Y-cur X-orig Y-orig) (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-orig Y-cur X-orig Y-orig) ] ; Y runs out first, recycle [ (null? Y-cur) (fmap2lcm-r fn X-cur Y-orig X-orig Y-orig) ] ; process first of both and recurse. [ else (cons (fn (first X-cur) (first Y-cur)) (fmap2lcm-r fn (rest X-cur) (rest Y-cur) X-orig Y-orig)) ] ))) ; We are still dragging the original input lists through the recursion. (define fmap2lcm (lambda (fn X Y) ; handle special boundary case of empty input lists (if (or (null? X) (null? Y)) '() (fmap2lcm-r fn X Y X Y))))