Skip to content

Instantly share code, notes, and snippets.

@divs1210
Last active June 22, 2024 14:23
Show Gist options
  • Save divs1210/09a40bb2830fbcee11d3806888ef0f62 to your computer and use it in GitHub Desktop.
Save divs1210/09a40bb2830fbcee11d3806888ef0f62 to your computer and use it in GitHub Desktop.
extrapolate: like iterate, but different
(defn extrapolate*
[gen-next shrink v]
(lazy-seq
(let [next-item (gen-next v)
new-v (shrink (conj v next-item))]
(cons next-item
(extrapolate* gen-next shrink new-v)))))
(defn extrapolate
"Returns a lazy seq produced by extrapolating `coll` with given rules.
Maintains a backing vector initialized as (vec coll).
On each iteration,
- (gen-next v) is called to produce the next item
- (shrink v) is called to shrink the backing vector, defaults to `identity`"
([gen-next coll]
(extrapolate gen-next identity coll))
([gen-next shrink coll]
(concat coll (extrapolate* gen-next shrink (vec coll)))))
;; USAGE
;; =====
;; without shrink (retains head)
;; ==============
(def primes
(extrapolate (fn [found-primes]
(let [last-prime (peek found-primes)]
(loop [probable-prime (inc last-prime)]
(if (not-any? #(zero? (mod probable-prime %))
found-primes)
probable-prime
(recur (inc probable-prime))))))
[2]))
primes ;; => (2 3 5 7 11 13 ...)
;; with shrink
;; ===========
(defn vtake-last
[n v]
(let [size (count v)]
(subvec v
(max (- size n) 0)
size)))
(def fibs
(extrapolate #(apply + %)
#(vtake-last 2 %)
[0 1]))
fibs ;; => (0 1 1 2 3 5 8 ..)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment