walk sequence of range boundaries values for source and filter ranges
add lower level logic for walking the boundary markers of sets but distinguish between a source range and a filter range when looking at the start and end boundary behavior
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
(ns challenge.discrete-value-range)
|
||||
(ns challenge.discrete-value-range
|
||||
(:require [clojure.core.match :refer [match]]))
|
||||
|
||||
(defprotocol DiscreteValueRange
|
||||
"A protocol for generic behavior on Ranges over
|
||||
@@ -29,7 +30,7 @@
|
||||
(start [this])
|
||||
(end [this])
|
||||
(range-type [this])
|
||||
(union [range1 range2]))
|
||||
(union [this other]))
|
||||
|
||||
(defn- ordered-range-values
|
||||
"Builds an ordered list or 'fenceposts' for the start and end
|
||||
@@ -129,4 +130,51 @@
|
||||
(combine-abutting-ranges)))
|
||||
|
||||
(defn consolidate [ranges]
|
||||
(eduction consolidate-ranges-xf (ordered-range-values ranges)))
|
||||
(into #{} consolidate-ranges-xf (ordered-range-values ranges)))
|
||||
|
||||
(defn walk-range-boundaries [range-boundary-items]
|
||||
(let [close-working-range (fn [range-type start end ranges]
|
||||
(conj ranges (->discrete-value-range range-type
|
||||
start
|
||||
end)))]
|
||||
|
||||
(loop [[boundary-item & boundary-items] range-boundary-items
|
||||
in-filter-range nil
|
||||
in-source-range nil
|
||||
ranges #{}
|
||||
close-fn nil]
|
||||
(match [boundary-item]
|
||||
[nil]
|
||||
ranges
|
||||
|
||||
[{:boundary-type :start
|
||||
:range-source-type :source-range
|
||||
:type range-type
|
||||
:value new-working-range-start-value}]
|
||||
(recur boundary-items in-filter-range true ranges (partial close-working-range
|
||||
range-type
|
||||
new-working-range-start-value))
|
||||
|
||||
[{:boundary-type :end
|
||||
:range-source-type :source-range
|
||||
:value value}]
|
||||
(if in-filter-range
|
||||
(recur boundary-items in-filter-range false ranges nil)
|
||||
(recur boundary-items in-filter-range false (close-fn value ranges) nil))
|
||||
|
||||
[{:boundary-type :start
|
||||
:range-source-type :filter-range
|
||||
:prev-value prev-value}]
|
||||
(if close-fn
|
||||
(recur boundary-items true in-source-range (close-fn prev-value ranges) nil)
|
||||
(recur boundary-items true in-source-range ranges close-fn))
|
||||
|
||||
[{:boundary-type :end
|
||||
:range-source-type :filter-range
|
||||
:type range-type
|
||||
:next-value new-working-range-start-value}]
|
||||
(if in-source-range
|
||||
(recur boundary-items false in-source-range ranges (partial close-working-range
|
||||
range-type
|
||||
new-working-range-start-value))
|
||||
(recur boundary-items false in-source-range ranges close-fn))))))
|
||||
|
||||
Reference in New Issue
Block a user