I've been playing with Clojure for the last few evenings, going through the well known 99 problems (I'm using a set adapted for Scala).
Given a set S and a no. of items K, returns all possible combinations of K items that can be taken from set S.
Here's my solution:
(defn combinations [k s] (cond (> k (count s)) nil ;not enough items in sequence to form a valid combination (= k (count s)) [s] ;only one combination available: all items (= 1 k) (map vector s) ;every item (on its own) is a valid combination :else (reduce concat (map-indexed (fn [i x] (map #(cons x %) (combinations (dec k) (drop (inc i) s)))) s)))) (combinations 3 ['a 'b 'c 'd 'f])
My basic solution is to take each item from the given sequence (
map-indexed) and recurse to generate combinations of size
K - 1 from the remaining sequence. The termination conditions are described above.
I'm still a complete Clojure newbie and would welcome comments on structure, efficiency, readability, resemblance to idiomatic Clojure, etc. Feel free to be brutal, but please remember I've been doing Clojure for only a few hours :)
I'm less interested in alternative mathematical methods for generating k-combinations, more interested in feedback on whether this is passable Clojure.