这是我正在尝试运行的功能......
(defn mongean [cards times]
(let [_cards (transient cards)]
(loop [i 0 c (get cards i) _count (count cards) _current (/ _count 2)]
(assoc! _cards _current c)
(if ((rem i 2) = 0)
(def _newcur (- _current (inc i)))
(def _newcur (+ _current (inc i))))
(if (<= i _count)
(recur (inc i) (get cards i) _count _newcur )))
(persistent! _cards)))
导致此例外......
Exception in thread "main" java.lang.ClassCastException: clojure.lang.PersistentHashSet$TransientHashSet cannot be cast to clojure.lang.ITransientAssociative
对clojure不熟悉,我也很欣赏对我上述方法的任何建设性批评。目标是获取一个List,并返回一个重新排序的列表。
答案 0 :(得分:8)
我假设您正在尝试实施Mongean shuffle。您的方法非常迫切,您应该尝试使用更实用的方法。
这是一个可能的实现,如果我们计算卡的最终顺序(根据维基百科公式),然后我们使用内置的replace
函数来进行映射:
(defn mongean [cards]
(let [num-cards (count cards)
final-order (concat (reverse (range 1 num-cards 2)) (range 0 num-cards 2))]
(replace cards final-order)))
user> (mongean [1 2 3 4 5 6 7 8])
(8 6 4 2 1 3 5 7)
答案 1 :(得分:2)
你怎么称呼这个功能?看起来你正在传递一个集合,因此它的瞬态版本也将是一个集合,因此不能与任何assoc
函数一起使用,因为它们处理关联数据结构和向量:
user=> (assoc #{} :a 1)
ClassCastException clojure.lang.PersistentHashSet cannot be cast to clojure.lang.Associative clojure.lang.RT.assoc (RT.java:691)
user=> (assoc! (transient #{}) :a 1)
ClassCastException clojure.lang.PersistentHashSet$TransientHashSet cannot be cast to clojure.lang.ITransientAssociative clojure.core/assoc! (core.clj:2959)
; the following works as it uses maps and vectors
user=> (assoc {} :a 1)
{:a 1}
user=> (assoc! (transient {}) :a 1)
#<TransientArrayMap clojure.lang.PersistentArrayMap$TransientArrayMap@65cd1dff>
user=> (assoc [] 0 :a)
[:a]
现在,让我们尝试讨论代码本身。如果没有更多关于你想达到的目标的提示,那么关注你的代码并尝试理解目标是什么有点困难,但作为一般性评论:
您有一个times
输入参数,根本不使用
你应该使用瞬态变异的结果,而不是假设瞬态变异就会发生变异
如果可以的话,请避免使用瞬态,它们仅仅是一种性能优化
绑定_current (/ _count 2)
可能不是您想要的,因为(/ 5 2)
确实返回5/2
并且您似乎想要将其用作结果中的位置
_count
之类的常量不需要成为loop
绑定的一部分,您可以使用外部let
,这样您就不必将它们传递给let
每次迭代
使用def
代替(if ((rem 1 2) = 0))
来命名函数内的内容
map
绝对不是您想要的
现在,不考虑改组算法,如果你需要重新排列一个序列,你可能只生成一系列新的位置,[position card]
使用原始卡片来生成reduce
对,最后{ {1}}将卡片放在新位置,使用原始序列作为种子:
(defn generate [coll] ; counts down from (count coll) to 0, change to
; implement your shuffling algorithm
(range (dec (count coll)) -1 -1))
(defn mongean [cards times]
(let [positions (generate cards) ; get the new positions
assemble (fn [dest [pos card]] ; assoc the card at the wanted position
(assoc dest pos card))]
(reduce assemble cards (map vector positions cards))))
如果您只是想洗牌:
(defn mongean [cards times] (shuffle cards))