5
\$\begingroup\$

My goal is to simulate a Pile shuffle of a vector. It takes 2 optional arguments for the number of piles to use and how many times to perform the shuffle.

As this is my first attempt at clojure code, I'm fairly sure I'm doing something terribly wrong here. I'm concerned with speed, efficiency, and indentation style. I'd also appreciate any pointers that would make this function more generic (maybe not restricting to vectors, but general collections).

(defn pile
  ([cards] (pile cards 3 1))
  ([cards num_piles] (pile cards num_piles 1))
  ([cards num_piles times]
    (loop [i 1
           piles (transient (vec (map (fn [p] []) (range num_piles))))
           the_pile 0]
      (if (<= i (count cards))
        (recur (inc i)
               (assoc!
                 piles
                 the_pile
                 (vec (concat [(nth cards (dec i))]
                               (nth piles the_pile))))
               (rem i num_piles))
        (if (> times 1)
          (pile (reduce into (persistent! piles)) num_piles (dec times) )
          (vec (reduce into (persistent! piles))))))))
\$\endgroup\$

1 Answer 1

3
\$\begingroup\$

You need loop/recur very rarely in most code, and almost never for operating on collections/sequences. Using the standard library sequence functions, it’s possible to do the main pile shuffle with just a handful of expressions:

(->> (range (dec n) -1 -1) (mapcat #(take-nth n (drop % cards))) reverse)

It takes some getting used to, and familiarity with the Clojure standard library. When I was first getting started, I found it immensely helpful to read the clojure/core.clj code. It isn’t all idiomatic because it’s building the support for the idioms as it goes, but it demonstrates what Clojure makes possible and how it makes those things possible.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.