-
Notifications
You must be signed in to change notification settings - Fork 6
Expand file tree
/
Copy pathsorted_value_map.clj
More file actions
39 lines (34 loc) · 1.26 KB
/
sorted_value_map.clj
File metadata and controls
39 lines (34 loc) · 1.26 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
(ns advent-2021-clojure.sorted-value-map
(:refer-clojure :exclude [assoc merge-with]
:rename {dissoc c-dissoc, first c-first}))
(def empty-map {:key-to-value {}, :value-to-keys (sorted-map)})
(defn- value-of [svm k] (get-in svm [:key-to-value k]))
(defn- keys-of [svm v] (get-in svm [:value-to-keys v]))
(defn dissoc [svm k]
(if-some [old-value (value-of svm k)]
(if (= #{k} (keys-of svm old-value))
(-> svm
(update :key-to-value c-dissoc k)
(update :value-to-keys c-dissoc old-value))
(-> svm
(update :key-to-value c-dissoc k)
(update-in [:value-to-keys old-value] disj k)))
svm))
(defn assoc [svm k v]
(if (= v (value-of svm k))
svm
(-> svm
(dissoc k)
(assoc-in [:key-to-value k] v)
(update-in [:value-to-keys v] #(if % (conj % k) (sorted-set k))))))
(defn first [svm]
(when-some [[v ks] (-> svm :value-to-keys c-first)]
[(c-first ks) v]))
(defn merge-with [f svm other-map]
(reduce-kv (fn [acc k v] (if-some [curr-v (value-of svm k)]
(if (= curr-v (f v curr-v))
acc
(assoc acc k v))
(assoc acc k v)))
svm
other-map))