## DEV Community is a community of 639,914 amazing developers

We're a place where coders share, stay up-to-date and grow their careers.

loading...

# Discussion on: Daily Challenge #249 - Incremental Changes @nobody • Edited

Clojure - Level 2 🌟🌟

``````(ns dailyChallenge.IncrementalChange249
(^:level2))

;; recursive function w/ tail-end optimization
(defn algo [number, step, iterations]
{:pre (>= iterations 1)}
(let [accum
(loop [ result [number] itr iterations]
(if (= 1 itr)
(conj result step)
(recur result (dec itr))))]
(apply + accum))

(deftest test-algo
(is (= 52 (algo 2 5 10))
(is (= 35 (algo 17, 3, 6)))

(run-tests 'test-algo)
`````` Paula Gearon

Compared to your "level 1", this is more like the question asked, since it asks for an algorithm rather than the answer. (I totally agree that it should be `(+ number (* step iterations))`).

In Clojure it's usually better to preference core functions, followed by `reduce`, followed by `loop`/`recur`.

The clojure.core function approach is just:

``````(defn algo
[number step iterations]
(->> number
(iterate (partial + step))
(drop iterations)
first))
``````

But that's really using `iterate` to do the algorithm part. So `reduce` might be more in the spirit of things. It's shorter too 🙂

``````(defn algo
[number step iterations]
(->> (repeat step)
(take iterations)
(reduce + number)))
`````` @nobody • Edited

Awesome breakdown! Thanks Paula. 🙏🏿

I feel like you're right on the hierarchy of abstraction to use for Clojure functions (there's just so many, and many of them are composed)._

I could've just used pure-recursion without `loop/recur` but I don't get the power of the AST's tail-end optimizer for loops. Thank you for reminding me of the thread-macro.