;; Function to compute the intersection of two intervals.
;; If the intersection is empty, the function returns #f as the lower limit
;; of the intersection.
(define (intersect-interval a b)
;; Assume that (car a) <= (cadr a) and (car b) <= (cadr b)
;; Get the lower limit of the intersection.
;; If there isn't one, return #f
(define (lower-limit)
(if (< (cadr a) (car b))
#f
(car b)))
;; Get the upper limit of the intersection.
(define (upper-limit)
(min (cadr a) (cadr b)))
;; Let's make our life simpler.
;; Make sure that (car a) is less than (car b)
;; for the core computation.
(if (> (car a) (car b))
(intersect-interval b a)
(list
(lower-limit)
(upper-limit)))
)
;; Function that computes the valid intersections of two sets of intervals.
(define (intersect-interval-sets seta setb)
;; Helper function that takes one item from the first set and iterates over the
;; items of the second set. It computes the intersection of the item from the first set
;; and each item of the second set. If there is a valid intesection, it adds it to the output.
(define (make-intersections-2 item lst2 out)
(if (null? lst2)
out
(begin
(let ((ints (intersect-interval item (car lst2))))
(if (eq? #f (car ints))
(make-intersections-2 item (cdr lst2) out)
(make-intersections-2 item (cdr lst2) (append out (list ints))))))))
;; Helper function that iterates over the items of the first list and calls the previous
;; function using each item of the first list and the second list.
(define (make-intersections-1 lst1 lst2 out)
(if (null? lst1)
out
(make-intersections-1 (cdr lst1) lst2 (make-intersections-2 (car lst1) lst2 out))))
;; Start the recursion and return the result.
(make-intersections-1 seta setb '())
)
Testing at repl.it
(define seta '((2 3) (100 200))) (define setb '((5 10) (90 120) (110 300))) (intersect-interval-sets seta setb) => ((100 120) (110 200))