# Sum until limit with Clojure

The way Clojure code solves things are very elegant, but unusual for people without a solid background in fully functional programming languages (like me).

I’ve tried to solve simple problems from Project Euler using Clojure, but failed due the lack of that background.

One problem I was trying to solve was to sum the numbers until a limit. Let’s say I want the sum until 5, so, the math would be `1 + 2 + 3 + 4 + 5 = 15`.

In JavaScript I would do something like:

``````function sumUntilLimit(limit) {
let counter = 0,
result = 0;
while(counter <= limit) {
result += counter;
counter++;
}
return result;
}

sumUntilLimit(5); // 15
``````

How would you do accomplish the right result using Clojure?

I’m pretty new to all of this but I would write that function in clojure like:

`(defn sum-until-limit [limit] (apply + (range (inc limit))))`

Not sure how to do formatting on here so I wouldn’t have that as one line. But basically `apply` is going to take a given function (in this case, `+`) and apply it as the operand for all the items in a given collection. So `(apply + [1 2 3])` will give you `(+ 1 2 3)`. So in this case we take the range from 0 to `(inc limit)` because we want to add 1 to the limit given because `range` is non inclusive. `(range 6)` gives us the sequence: `(0 1 2 3 4 5)` I hope I’m explaining all that correctly. Seems to work in my repl at least.

2 Likes

Note first that

(range 1 6)

returns
(1 2 3 4 5)

and

(apply + (range 1 6))

returns

15

2 Likes

I like that suggestion. That also allows you to use this for multiplication too as it takes the `0` out of the equation. You still need to increment your “limit” so it would have to be `(apply + (range 1 (inc limit))`. My first suggestion might be more elegant now but still isn’t as generic.

Great approaches guys. I knew about apply for it’s very common in JavaScript, but didn’t know that there was a `range` function as in Python.

Thank you.

A few other ways to explore:

``````(defn sum-until
[limit]
(reduce + (range 1 (inc limit))))
``````

Recursively, without using range:

``````(defn sum-until
[limit]
(loop [limit limit sum 0]
(if (pos? limit)
(recur (dec limit)
(+ sum limit)) sum)))
``````

Iteratively, without using range:

``````(defn sum-until
[limit]
(let [result (atom 0)
limit (atom limit)]
(while (pos? @limit)
(swap! result + @limit)
(swap! limit dec))
@result))
``````

Using iterate (a type of immutable generator), without range

``````(defn sum-until [limit]
(->> (iterate (fn [[result counter]]
[(+ result counter)
(inc counter)])
[0 1])
(take-while #(<= (last %) (inc limit)))
(map first)))
``````

That last one is cool, because you can actually generate all result at every step:

``````(sum-until 5)
;; Returns: (0 1 3 6 10 15)
``````

Which you can also implement in a mutable way:

``````(defn sum-until [limit]
(let [counter (atom 0)]
(->> (iterate #(do (swap! counter inc)
(+ @counter %))
0)
(take-while (fn[_] (>= limit @counter))))))
``````

Keeping in mind it is most idiomatic to use `range` with either `reduce` or `apply`.

4 Likes

Okay – that iterate one taught me few things. Thanks! Now I’m reading https://clojuredocs.org/clojure.core/iterate and imagining the possibilities…

You can also obtain the intermediate steps by using `reductions` instead of `reduce` in your first implementation.

This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.