How does one write a function to split a list and then merge it back together such that the resulting list represents the shuffle of a deck?
The list (1 2 3 4 5 6 7 8 9 10)
should end up as (1 6 2 7 3 8 4 9 5 10)
Is there a way to use split-at
or reduce
or some other function to achieve this?
So far I'm here:
(defn shuffle [cards]
(split-at (/ (count cards) 2) cards)
)
(apply interleave (split-at 5 (range 1 11)))
(1 6 2 7 3 3 8 4 9 5 10)
Clojure has an excellent selection of sequence functions.
user> (range 1 11)
(1 2 3 4 5 6 7 8 9 10)
user> (apply mapcat list (split-at 5 (range 1 11)))
(1 6 2 7 3 8 4 9 5 10)
You can get an overview at the clojure cheatsheet , it's a little out of date but mostly still relevant, and gives a good overview of the Clojure basics.
Split like you already have, then zip the two halves together and flatten:
(defn shuffle [cards]
(->> cards
(split-at (/ (count cards) 2))
(apply map list)
(flatten)))
(shuffle '(1 2 3 4 5 6 7 8 9 10)) ;=> (1 6 2 7 3 8 4 9 5 10)
Of course if you want a “truly” random shuffle, use clojure.core/shuffle
.
A general solution is
(defn riffle [s]
(let [v (vec s), c (quot (count v) 2)]
(interleave (subvec v 0 c) (subvec v c))))
In this case
(riffle '(1 2 3 4 5 6 7 8 9 10))
; (1 6 2 7 3 8 4 9 5 10)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.