🎉 Exercism Research is now launched. Help Exercism, help science and have some fun at research.exercism.io 🎉
Avatar of Shardik42

Shardik42's solution

to Accumulate in the Clojure Track

Published at Aug 16 2020 · 0 comments
Instructions
Test suite
Solution

Implement the accumulate operation, which, given a collection and an operation to perform on each element of the collection, returns a new collection containing the result of applying that operation to each element of the input collection.

Given the collection of numbers:

  • 1, 2, 3, 4, 5

And the operation:

  • square a number (x => x * x)

Your code should be able to produce the collection of squares:

  • 1, 4, 9, 16, 25

Check out the test suite to see the expected function signature.

Restrictions

Keep your hands off that collect/map/fmap/whatchamacallit functionality provided by your standard library! Solve this one yourself using other basic tools instead.

Source

Conversation with James Edward Gray II https://twitter.com/jeg2

Submitting Incomplete Solutions

It's possible to submit an incomplete solution so you can see how others have completed the exercise.

accumulate_test.clj

(ns accumulate-test
  (:require [clojure.test :refer [deftest is]]
            accumulate))

(defn- square [n] (* n n))

(defn- to-s [xs] (apply str xs))

(deftest empty-accumulation
  (is (= [] (accumulate/accumulate square []))))

(deftest accumulate-squares
  (is (= [1 4 9] (accumulate/accumulate square [1 2 3]))))

(deftest accumulate-upcases
  (is (= ["HELLO", "WORLD"]
         (->> ["hello" "world"]
              (accumulate/accumulate clojure.string/upper-case)
              (map to-s)))))

(deftest accumulate-reversed-strings
  (is (= ["eht" "kciuq" "nworb" "xof" "cte"]
         (->> ["the" "quick" "brown" "fox" "etc"]
              (accumulate/accumulate reverse)
              (map to-s)))))

(deftest accumulate-recursively
  (is (= [["a1" "a2" "a3"] ["b1" "b2" "b3"] ["c1" "c2" "c3"]]
         (-> #(accumulate/accumulate (fn [n] (str % n)) [1 2 3])
             (accumulate/accumulate "abc")))))
(ns accumulate)

(defn accumulate
  [f [x & xs :as coll]]
  (if (seq coll)
    (lazy-cat [(f x)] (accumulate f xs))
    []))

(comment
  (take 5 (accumulate #(* % 2) (range))))

Community comments

Find this solution interesting? Ask the author a question to learn more.

Shardik42's Reflection

Three solutions: already knew how to do list comprehension, but learned about `lazy-seq` and `lazy-cat` as well.