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).
Problem 26
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.