通过合并Clojure中的列表来进行随机播放

时间:2014-05-15 00:56:08

标签: clojure

如何编写一个函数来拆分列表然后将它合并回来,以便结果列表代表一个套牌的洗牌?

列表(1 2 3 4 5 6 7 8 9 10)最终应为(1 6 2 7 3 8 4 9 5 10)

有没有办法使用split-atreduce或其他功能来实现这一目标?

到目前为止,我在这里:

(defn shuffle [cards] 
  (split-at (/ (count cards) 2) cards)
)

4 个答案:

答案 0 :(得分:6)

(apply interleave (split-at 5 (range 1 11)))

(1 6 2 7 3 8 4 9 5 10)

答案 1 :(得分:3)

Clojure具有出色的序列功能选择。

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)

您可以在the clojure cheatsheet获得一个概述,它有点过时但大部分仍然相关,并且对Clojure基础知识有了很好的概述。

答案 2 :(得分:1)

像你已经拥有的那样分裂,然后将zip两半放在一起并展平:

(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)

当然,如果你想要一个“真正”随机的随机播放,请使用clojure.core/shuffle

答案 3 :(得分:0)

一般解决方案是

(defn riffle [s]
  (let [v (vec s), c (quot (count v) 2)]
    (interleave (subvec v 0 c) (subvec v c))))

在这种情况下

(riffle '(1 2 3 4 5 6 7 8 9 10))
; (1 6 2 7 3 8 4 9 5 10)