Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

3Sum using for in Clojure

Tags:

clojure

I had this classic algo exercise: How many triples sum to zero in this array? No problem implementing this in Java:

int count = 0;
for (int i = 0; i < array.length - 2; i++) {
  (for int j= i+1; j < array.length -1; j++) {
    (for int k = j + 1; k < array.length; k++) {
      if (array[i] + array[j] + array[k] == 0) {
        count++;
      }
    }
  }
}
return count;

How would I do that in Clojure though? I asked myself: How can I do nested loops in Clojure.

But this question and answer doesn't really address my problem, as it takes two identical arrays and combines all the elements (also the identical elements, e.g. 1 and 1).

Related question: How do I get all combinations of triples from a collection?

Note: We were explicitly asked not to sort the array. I know that there are faster algorithms for this.

EDIT: Added "== 0" to condition.

like image 601
Mario Trost Avatar asked Aug 14 '26 05:08

Mario Trost


1 Answers

also you can do it with list comprehension, without operating indices at all:

user> (def data [1 -2 1 1 -3 2])
#'user/data

user> (defn tails [data]
        (take-while seq (iterate rest data)))
#'user/tails

user> (for [[x & xs] (tails data)
            [y & ys] (tails xs)
            [z] (tails ys)
            :when (zero? (+ x y z))]
        [x y z])

;;=> ([1 -2 1] [1 -2 1] [1 -3 2] [-2 1 1] [1 -3 2] [1 -3 2])
like image 188
leetwinski Avatar answered Aug 18 '26 14:08

leetwinski



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!