start of protocol for discrete value ranges

This commit is contained in:
2026-01-10 16:53:52 -06:00
parent d908c5c656
commit 2f654bc1e2
3 changed files with 86 additions and 0 deletions

3
.gitignore vendored
View File

@@ -1 +1,4 @@
.cpcache .cpcache
.clj-kondo/
.lsp/
.nrepl-port

View File

@@ -0,0 +1,30 @@
(ns challenge.discrete-value-range)
(defprotocol DiscreteValueRange
"A protocol for generic behavior on Ranges over
discrete values.
This is for discrete values as we want to be
able to determine the value before the range
start and the value immediately after the range end.
By using discrete values we:
1. Determine if two ranges abut (touch) each other, and
can therefore be combined into a single range
2. Can combine overlapping by listing all ranges' start
and end values, and using a stack's push/pop functionality
to know if we are in a larger composite range, similiar
to parenthesis matching. e.g. If I encounter two range
start items, I know I should be expecting two end values,
even if the range is 'unbounded', there should be a MIN/MAX
value specified.
3. Know the discrete values for both before and or after the range
(even if a MIN/MAX marker) value that we can use to compare
that before/after values against other values that the range
is over.
"
(abuts [this ^DiscreteValueRange other])
(value-before [this])
(value-after [this])
(start [this])
(end [this]))

View File

@@ -0,0 +1,53 @@
(ns challenge.discrete-value-range-test
(:require
[clojure.test :refer [deftest testing is]]
[challenge.discrete-value-range :as range]))
(deftype IntInclusiveDiscreteValueRange
[^int start ^int end]
range/DiscreteValueRange
(abuts [_this other]
(or (= 1 (abs (- start (.end other))))
(= 1 (abs (- end (.start other))))))
(value-before [__this]
(dec start))
(value-after [_this]
(inc end))
(start [_this]
start)
(end [_this]
end)
Object
(toString [_this]
(str start ".." end))
(equals [_this other]
(and (= start (.start other))
(= end (.end other)))))
(defn int-range-inclusive [start end]
(assert (<= start end))
(->IntInclusiveDiscreteValueRange start end))
(deftest integer-ranges-sanity-test
(testing "value equality"
(is (= (int-range-inclusive 0 1)
(int-range-inclusive 0 1))))
(testing "abuts"
(is (= true (range/abuts (int-range-inclusive 0 1)
(int-range-inclusive 2 3))))
(is (= true (range/abuts (int-range-inclusive 1 1)
(int-range-inclusive 2 3))))
(is (= true (range/abuts (int-range-inclusive 4 7)
(int-range-inclusive 2 3))))
(is (= false (range/abuts (int-range-inclusive 4 7)
(int-range-inclusive 1 2)))))
(testing "value-before"
(is (= 0 (range/value-before (int-range-inclusive 1 8)))))
(testing "value-after"
(is (= 9 (range/value-after (int-range-inclusive 1 8)))))
(testing "start"
(is (= 1 (range/start (int-range-inclusive 1 8)))))
(testing "end"
(is (= 8 (range/end (int-range-inclusive 1 8))))))