Range consolidation: Difference between revisions
Content added Content deleted
Line 379: | Line 379: | ||
[4, 3], [2, 1], [-1, -2], [3.9, 10] -> [-2, -1], [1, 2], [3, 10] |
[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] |
[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> |
</pre> |
||