Create initial project structure with tests and reader
This commit is contained in:
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
.cpcache
|
||||||
7
.tool-versions
Executable file
7
.tool-versions
Executable file
@@ -0,0 +1,7 @@
|
|||||||
|
# https://asdf-vm.com/
|
||||||
|
|
||||||
|
# Java:
|
||||||
|
java temurin-17.0.7+7
|
||||||
|
|
||||||
|
# Clojure:
|
||||||
|
clojure 1.11.1.1342
|
||||||
8
deps.edn
Normal file
8
deps.edn
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
{:deps {org.clojure/clojure {:mvn/version "1.11.2"}
|
||||||
|
org.threeten/threeten-extra {:mvn/version "1.8.0"}}
|
||||||
|
:paths ["src"]
|
||||||
|
:aliases {:test {:extra-paths ["test"]
|
||||||
|
:extra-deps {com.cognitect/test-runner {:git/url "https://github.com/cognitect-labs/test-runner.git"
|
||||||
|
:git/sha "dfb30dd"
|
||||||
|
:git/tag "v0.5.1"}}
|
||||||
|
:exec-fn cognitect.test-runner.api/test}}}
|
||||||
6
src/challenge/core.clj
Normal file
6
src/challenge/core.clj
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
(ns challenge.core
|
||||||
|
(:require [clojure.set :as set])
|
||||||
|
(:import (java.time LocalDate Period)
|
||||||
|
(org.threeten.extra LocalDateRange)))
|
||||||
|
|
||||||
|
(defn difference [& input])
|
||||||
34
src/challenge/readers.clj
Normal file
34
src/challenge/readers.clj
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
(ns challenge.readers
|
||||||
|
(:import (org.threeten.extra LocalDateRange)))
|
||||||
|
|
||||||
|
(defn local-date-range [s] (LocalDateRange/parse s))
|
||||||
|
|
||||||
|
(defn local-date-range-as-iso-interval
|
||||||
|
"Print the given LocalDateRange `ldr` as an ISO 8601-1:2019 interval in
|
||||||
|
<start>/<duration> format."
|
||||||
|
[ldr]
|
||||||
|
{:pre [(instance? LocalDateRange ldr)]}
|
||||||
|
(let [start (.getStart ldr)
|
||||||
|
period (.toPeriod ldr)]
|
||||||
|
;; NB: when the start date is the first day of the month and the duration is
|
||||||
|
;; one month, consider printing the interval as "YYYY-MM/P1M". This has the
|
||||||
|
;; advantage of naturally segregating month intervals from day intervals in
|
||||||
|
;; lexical sorts but has the disadvantage of not being parseable by the
|
||||||
|
;; LocalDateRange class nor by its sibling Interval class.
|
||||||
|
(str start "/" period)))
|
||||||
|
|
||||||
|
;; We elect to print a LocalDateRange using the ISO 8601-1:2019 <start>/<period>
|
||||||
|
;; representation. This is a compact and standardized representation that high-
|
||||||
|
;; lights our expected use case of specific periods (one day and one month).
|
||||||
|
;; The use of a LocalDate to represent the date-only start point is not well
|
||||||
|
;; publicized, probably because the relevant ISO standard (ISO 8601-2:2019) is
|
||||||
|
;; aggressively copyrighted and the use cases are few compared to other elements
|
||||||
|
;; of the standard.
|
||||||
|
(defmethod print-dup LocalDateRange
|
||||||
|
[o ^java.io.Writer w]
|
||||||
|
(doto w
|
||||||
|
(.write "#st/local-date-range \"")
|
||||||
|
(.write (local-date-range-as-iso-interval o))
|
||||||
|
(.write "\"")))
|
||||||
|
|
||||||
|
(defmethod print-method LocalDateRange [o ^java.io.Writer w] (print-dup o w))
|
||||||
1
src/data_readers.clj
Normal file
1
src/data_readers.clj
Normal file
@@ -0,0 +1 @@
|
|||||||
|
{st/local-date-range challenge.readers/local-date-range}
|
||||||
0
src/data_readers.edn
Normal file
0
src/data_readers.edn
Normal file
47
test/challenge_test.clj
Normal file
47
test/challenge_test.clj
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
(ns challenge-test
|
||||||
|
(:require [challenge.core :refer [difference]]
|
||||||
|
[challenge.readers]
|
||||||
|
[clojure.test :refer [deftest is testing]]))
|
||||||
|
|
||||||
|
(def week0 #st/local-date-range "2024-01-01/P7D")
|
||||||
|
(def week1 #st/local-date-range "2024-01-08/P7D")
|
||||||
|
(def week2 #st/local-date-range "2024-01-15/P7D")
|
||||||
|
(def week3 #st/local-date-range "2024-01-22/P7D")
|
||||||
|
(def extra #st/local-date-range "2024-01-29/P3D")
|
||||||
|
(def month0 #st/local-date-range "2024-01-01/P1M")
|
||||||
|
|
||||||
|
(deftest unary
|
||||||
|
(is (= #{week0}
|
||||||
|
(difference #{week0})))
|
||||||
|
(testing "compresses results"
|
||||||
|
(is (= #{month0}
|
||||||
|
(difference #{week0 week1 week2 week3 extra})))))
|
||||||
|
|
||||||
|
(deftest binary
|
||||||
|
(testing "equals"
|
||||||
|
(is (= #{}
|
||||||
|
(difference #{week0} #{week0})))
|
||||||
|
(is (= #{}
|
||||||
|
(difference #{week0 week1} #{week0 week1}))))
|
||||||
|
(testing "overlapped by"
|
||||||
|
(is (= #{#st/local-date-range "2024-01-01/P4D"}
|
||||||
|
(difference #{week0}
|
||||||
|
#{#st/local-date-range "2024-01-05/P10D"})))
|
||||||
|
(is (= #{#st/local-date-range "2024-01-01/P4D"}
|
||||||
|
(difference #{week0 week1}
|
||||||
|
#{#st/local-date-range "2024-01-05/P10D"}))))
|
||||||
|
(testing "met by"
|
||||||
|
(is (= #{week0}
|
||||||
|
(difference #{week0} #{week1}))))
|
||||||
|
(testing "contains"
|
||||||
|
(is (= #{week0 #st/local-date-range "2024-01-15/P17D"}
|
||||||
|
(difference #{month0} #{week1}))))
|
||||||
|
(testing "during"
|
||||||
|
(is (= #{}
|
||||||
|
(difference #{week1} #{month0})))))
|
||||||
|
|
||||||
|
(deftest variadic
|
||||||
|
(is (= #{week0 extra}
|
||||||
|
(difference #{month0}
|
||||||
|
#{week1}
|
||||||
|
#{week2 week3}))))
|
||||||
Reference in New Issue
Block a user