-
Notifications
You must be signed in to change notification settings - Fork 7
/
sequence.clj
49 lines (44 loc) · 1.52 KB
/
sequence.clj
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
40
41
42
43
44
45
46
47
48
49
(ns com.yetanalytics.datasim.util.sequence)
(defn seq-sort
"Given a key-fn (that must return a number) and a vector of seqs, return the
items from all seqs ordered by that, ascending.
If incoming seqs are monotonic, the output is as well."
[key-fn seqs]
(lazy-seq
(when-let [seqs' (not-empty
(into []
(keep not-empty
seqs)))]
(let [[idx [head & rest-seq]]
(apply min-key (comp key-fn
first
second)
(map-indexed vector
seqs'))]
(cons head
(seq-sort
key-fn
(assoc seqs' idx rest-seq)))))))
;; https://clojuredocs.org/clojure.core/chunk#example-5c9cebc3e4b0ca44402ef6ec
(defn re-chunk
"takes a sequence (already chunked or not)
and produces another sequence with different chunking size."
[n xs]
(lazy-seq
(when-let [s (seq (take n xs))]
(let [cb (chunk-buffer n)]
(doseq [x s] (chunk-append cb x))
(chunk-cons (chunk cb) (re-chunk n (drop n xs)))))))
(comment
(require '[com.yetanalytics.datasim.util.random :as r])
(defn rand-monotonic-seq
[seed & [start]]
(let [rng (r/seed-rng seed)]
(rest (iterate #(+ % (r/rand rng)) (or start 0)))))
(let [ss (seq-sort
identity
(into []
(for [n (range 20)]
(take 10 (rand-monotonic-seq n)))))]
(= (sort ss) ss)) ;; => true
)