August 29, 2018

Just Juxt #15: Sequence Reductions (4clojure #60)

Reductions

Write a function which behaves like reduce, but returns each intermediate value of the reduction. Your function must accept either two or three arguments, and the return sequence must be lazy.

...but without using reductions, of course.

(ns live.test
  (:require [cljs.test :refer-macros [deftest is testing run-tests]]))

(defn my-reductions
  ([f vals]
   )
  ([f init vals]
   ))

(deftest my-reductions-test
  (is (= (take 5 (my-reductions + (range))) [0 1 3 6 10]))
  (is (= (my-reductions conj [1] [2 3 4]) [[1] [1 2] [1 2 3] [1 2 3 4]]))
  (is (= (last (my-reductions * 2 [3 4 5])) (reduce * 2 [3 4 5]) 120)))

(run-tests)

Here's our juxt solution, courtesy of nothsaevets:

(defn my-reductions
    ([f vals]
     (my-reductions f (first vals) (rest vals)))
    ([f init vals]
     (cons init
       ((fn inner
          [acc src]
          (when (seq src)
            (let [[head tail] ((juxt first rest) src)
                  result (f acc head)]
              (cons result
                (lazy-seq (inner result tail))))))
        init vals))))
        
(run-tests)
Tags: coding exercises KLIPSE 4clojure Cryogen juxt