如何编写一个函数来拆分列表然后将它合并回来,以便结果列表代表一个套牌的洗牌?
列表(1 2 3 4 5 6 7 8 9 10)
最终应为(1 6 2 7 3 8 4 9 5 10)
有没有办法使用split-at
或reduce
或其他功能来实现这一目标?
到目前为止,我在这里:
(defn shuffle [cards]
(split-at (/ (count cards) 2) cards)
)
答案 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)