(def integers (iterate inc 0))
(defn runavg [sq]
(fn [n]
(/ (reduce + (take (inc n) sq))
(inc n))))
((runavg integers) 5)
(def runavgs (map (runavg integers) (iterate inc 0)))
(take 5 runavgs)
(time (count (take 100 (map (runavg integers) (iterate inc 0))))) (time (count (take 1000 (map (runavg integers) (iterate inc 0)))))
(defn runavg
([lst] (runavg 0 0 lst))
([sum count lst]
(if (empty? lst) '()
(let [newsum (+ sum (first lst))
newcount (inc count)]
(cons (/ newsum newcount)
(runavg newsum newcount (rest lst)))))))
(runavg '(1 2 3 4 5))
(defn runavg
([lst] (runavg 0 0 lst))
([sum count lst]
(lazy-seq
(if (empty? lst) '()
(let [newsum (+ sum (first lst))
newcount (inc count)]
(cons (/ newsum newcount)
(runavg newsum newcount (rest lst))))))))
(take 5 (runavg integers))
(time (count (take 100 (runavg integers))))) (time (count (take 1000 (runavg integers))))) (time (count (take 10000 (runavg integers))))) (time (count (take 100000 (runavg integers)))))
(reduce + (range 1 10)) (reduce (fn[a x] (inc a)) (range 1 10))
(reduce (fn [[sum count] x] [(+ sum x) (inc count)]) [0 0] (range 1 10))
(defn reduce-seq [f acc sq]
(if (empty? sq) (list acc)
(let [next-acc (f acc (first sq))]
(cons acc (reduce-seq f next-acc (rest sq))))))
(defn reduce-seq [f acc sq]
(lazy-seq
(if (empty? sq) (list acc)
(let [next-acc (f acc (first sq))]
(cons acc (reduce-seq f next-acc (rest sq)))))))
(reduce-seq + 0 '(0 1 2 3 4 5)) (take 5 (reduce-seq + 0 integers))) (take 5 (reduce-seq * 1 (drop 1 integers)))
(reduce-seq
(fn [[sum count] x] [(+ sum x) (inc count)])
[0 0]
(range 5))
(defn running-average [sq]
(map #(apply / %)
(drop 1
(reduce-seq
(fn [[sum count] x] [(+ sum x) (inc count)])
[0 0]
sq))))
(running-average (range 5)) (take 10 (running-average integers))
(defn reduce-seq
([f acc sq]
(lazy-seq
(if (empty? sq) (list acc)
(let [next-acc (f acc (first sq))]
(cons acc (reduce-seq f next-acc (rest sq)))))))
([f sq] (reduce-seq f (first sq) (rest sq))))
(reduce + 0 '(1 2 3 4 5)) (reduce-seq + 0 '(1 2 3 4 5)) (reduce + '(1 2 3 4 5)) (reduce-seq + '(1 2 3 4 5)) (reduce + 0 (range 4)) (take 5 (reduce-seq + 0 (iterate inc 0))) (reduce + 0 '()) (reduce-seq + 0 '())
(reduce + '()) (reduce-seq + '())
(defn test-reduce-seq [reduce-seq]
(cond (not= (reduce-seq + 0 '(1 2 3 4 5)) '(0 1 3 6 10 15)) "fail"
(not= (reduce-seq + '(1 2 3 4 5)) '(1 3 6 10 15)) "fail"
(not= (take 5 (reduce-seq + 0 (iterate inc 0))) '(0 0 1 3 6)) "fail"
(not= (reduce-seq + 0 '()) '(0)) "fail"
(not= (reduce-seq + '(1)) '(1)) "fail"
(not= (reduce-seq + 1 '(1)) '(1 2)) "fail"
(not= (nth (reduce-seq + (iterate inc 0)) 10000) (* 1/2 10000 10001)) "fail"
(not= (reduce-seq #(assoc %1 %2 (inc (get %1 %2 0))) {} "aab")
'({} {\a 1} {\a 2} {\b 1, \a 2})) "fail"
(not= (reduce-seq + '()) '(0)) "fix me!!"
:else "pass"))
(test-reduce-seq reduce-seq)
(defn reduce-seq
([f acc sq]
(lazy-seq
(cons acc
(if (empty? sq) '()
(let [next-acc (f acc (first sq))]
(reduce-seq f next-acc (rest sq)))))))
([f sq] (reduce-seq f (first sq) (rest sq))))
(test-reduce-seq reduce-seq)
(defn reduce-seq
([f acc sq]
(lazy-seq
(cons acc
(if-let [sq (seq sq)]
(let [next-acc (f acc (first sq))]
(reduce-seq f next-acc (rest sq)))
'()))))
([f sq] (reduce-seq f (first sq) (rest sq))))
(test-reduce-seq reduce-seq)
(defn reduce-seq
([f acc sq]
(lazy-seq
(cons acc
(when-let [sq (seq sq)]
(reduce-seq f (f acc (first sq)) (rest sq))))))
([f sq] (reduce-seq f (first sq) (rest sq))))
(test-reduce-seq reduce-seq)
(defn reduce-seq
([f acc sq]
(cons acc
(lazy-seq
(when-let [sq (seq sq)]
(reduce-seq f (f acc (first sq)) (rest sq))))))
([f sq] (if-let [sq (seq sq)]
(reduce-seq f (first sq) (rest sq))
(list (f)))))
(test-reduce-seq reduce-seq)
(defn reduce-seq
([f acc sq]
(cons acc
(lazy-seq
(when-let [[head & tail] (seq sq)]
(reduce-seq f (f acc head) tail)))))
([f sq] (if-let [[head & tail] (seq sq)]
(reduce-seq f head tail)
(list (f)))))
(test-reduce-seq reduce-seq)
(defn reductions
([f acc sq]
(cons acc
(lazy-seq
(when-let [sq (seq sq)]
(reductions f (f acc (first sq)) (rest sq))))))
([f sq] (if-let [sq (seq sq)]
(reductions f (first sq) (rest sq))
(list (f)))))
"WARNING: reductions already refers to: #'clojure.core/reductions in namespace: user, being replaced by: #'user/reductions"
(defn reductions
"Returns a lazy seq of the intermediate values of the reduction (as
per reduce) of coll by f, starting with init."
{:added "1.2"}
([f coll]
(lazy-seq
(if-let [s (seq coll)]
(reductions f (first s) (rest s))
(list (f)))))
([f init coll]
(cons init
(lazy-seq
(when-let [s (seq coll)]
(reductions f (f init (first s)) (rest s)))))))
(running-average (range 5)) ;; (0 1/2 1 3/2 2)
ReplyDelete(map #(/ % 2) (range 5)) ;; (0 1/2 1 3/2 2)
;;i think you actually want
(running-average (range 5)) ;; (0 1/2 2/3 3/4 4/5)
maybe i'm misunderstanding what you want out of your running average but to me a running average would be the average of all numbers in the sequence up to the nth number.
Hi Brandon, thanks for the comment!
ReplyDeleteI was trying to calculate something like this:
sequence : 0 1 2 3 4 5 6
running sum : 0 1 3 6 10 15 21
element count : 1 2 3 4 5 6 7
quotients : 0 1/2 3/3 6/4 10/5 15/6 21/7
simplified : 0 1/2 1 3/2 2 5/2 3
(It's roughly the area of a triangle over the base of the triangle, x->1/2x*x/x)
How did you get yours?
whoops. i messed up my logic. i guess i was just confused that the running average of integers is simply n/2
ReplyDeleteThat's crazy, your final function turned out to be identical to the version in Clojure. Just a couple different var names and your signatures are in reverse order - everything else is the same.
ReplyDeleteGiven how flexible Clojure is, it's interesting that there's a clearly idiomatic way that emerges.