add transducer step to combine abutting ranges

ranges have previously been consolidated by having overlapping ranges be
combined, resuting in a (possibly) consolidated set of ranges, which
are now ordered by start and end dates.

Add a transducer step to walk those ranges and find any pairs of ranges
where the pair of ranges abutt each other, and combine them into
a single range.
This commit is contained in:
2026-01-10 18:28:24 -06:00
parent 98761a79ea
commit d0c78810f0
2 changed files with 69 additions and 5 deletions

View File

@@ -19,6 +19,13 @@
end)
(range-type [_this]
:int-range-inclusive)
(union [this other]
(when-not (range/abuts this other)
(throw (ex-info "Cannot union non-abutting ranges" {})))
(range/->discrete-value-range (.range-type this)
(min start (.start other))
(max end (.end other))))
Object
(toString [_this]
@@ -86,10 +93,10 @@
(range/consolidate [(int-range-inclusive 5 5)
(int-range-inclusive 5 5)])))
(is (= [(int-range-inclusive 0 1)
(int-range-inclusive 2 7)
(int-range-inclusive 3 7)
(int-range-inclusive 9 11)]
(range/consolidate [(int-range-inclusive 0 1)
(int-range-inclusive 2 4)
(int-range-inclusive 3 4)
(int-range-inclusive 3 7)
(int-range-inclusive 5 5)
(int-range-inclusive 9 11)
@@ -99,4 +106,28 @@
(int-range-inclusive 3 7)
(int-range-inclusive 5 5)
(int-range-inclusive 6 11)
(int-range-inclusive 5 5)]))))
(testing "conjoins abutting ranges"
(is (= [(int-range-inclusive 0 9)]
(range/consolidate [(int-range-inclusive 0 1)
(int-range-inclusive 2 4)
(int-range-inclusive 5 5)
(int-range-inclusive 6 9)
(int-range-inclusive 5 5)])))
(is (= [(int-range-inclusive 0 9)]
(range/consolidate [(int-range-inclusive 0 1)
(int-range-inclusive 2 3)
(int-range-inclusive 4 5)
(int-range-inclusive 6 9)
(int-range-inclusive 5 5)]))))
(testing "combines overlapping ranges and conjoins abutting ranges"
(is (= [(int-range-inclusive 0 7)
(int-range-inclusive 13 17)]
(range/consolidate [(int-range-inclusive 0 1)
(int-range-inclusive 2 4)
(int-range-inclusive 3 7)
(int-range-inclusive 5 5)
(int-range-inclusive 13 17)
(int-range-inclusive 5 5)])))))