(defn normalize [r] (let [[n1 n2] r] [(min n1 n2) (max n1 n2)])) (defn touch? [r1 r2] (let [[lo1 hi1] (normalize r1) [lo2 hi2] (normalize r2)] (or (<= lo2 lo1 hi2) (<= lo2 hi1 hi2)))) (defn consolidate-touching-ranges [rs] (let [lows (map #(apply min %) rs) highs (map #(apply max %) rs)] [ (apply min lows) (apply max highs) ])) (defn consolidate-ranges [rs] (loop [res [] rs rs] (if (empty? rs) res (let [r0 (first rs) touching (filter #(touch? r0 %) rs) remove-used (fn [rs used] (remove #(contains? (set used) %) rs))] (recur (conj res (consolidate-touching-ranges touching)) (remove-used (rest rs) touching))))))