Range consolidation: Difference between revisions

Line 379:
[4, 3], [2, 1], [-1, -2], [3.9, 10] -> [-2, -1], [1, 2], [3, 10]
[1, 3], [-6, -1], [-4, -5], [8, 2], [-6, -6] -> [-6, -1], [1, 8]
</pre>
 
 
=={{header|Clojure}}==
<lang Clojure>(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))))))</lang>
 
{{out}}
<pre>
(def test-data [ [[1.1 2.2]]
[[6.1 7.2] [7.2 8.3]]
[[4 3] [2 1]]
[[4 3] [2 1] [-1 -2] [3.9 10]]
[[1 3] [-6 -1] [-4 -5] [8 2] [-6 -6]] ])
 
(map consolidate-ranges test-data)
;; ==> ([[1.1 2.2]]
[[6.1 8.3]]
[[3 4] [1 2]]
[[3 10] [1 2] [-2 -1]]
[[1 8] [-6 -1] [-5 -4]]))
</pre>
 
Anonymous user