我可以在clojure中做一个确定性洗牌吗? [英] Can I make a Deterministic Shuffle in clojure?
问题描述
这是一种方法:
p> (def colors [redbluegreenyellowcyanmagentablackwhite ]
(defn color-shuffle [n]
(let [cs(nth(clojure.math.combinatorics / permutations colors)n)]
[ (drop 1 cs)]))
;使用(rand-int 40320)组成数字,然后硬编码:
(def color-shuffle-39038(color-shuffle 39038))
(color-shuffle-28193 ))
(def color-shuffle-5667(color-shuffle 5667))
(def color-shuffle-8194(color-shuffle 8194))
color-shuffle-39045; color-shuffle-39038)
(def color-shuffle-2345(color-shuffle 2345))
color-shuffle- [white(magentabluegreencyanyellowredblack)]
但是它需要一段时间来评估,看起来是浪费,而且不够。
有一些方法直接生成shuffle 39038,消耗所有的序列?
(我已经意识到我可以硬编码他们,或者带着一个宏的编译时间,这似乎有点垃圾。)
听起来像您想要 number permutations :
(def factorial (range))))
(defn factoradic [n] {:pre [(> = n 0)]}
(loop [a(list 0)nnp 2]
(if(zero?n)a(recur(conj a(mod np))(np)(inc p)))))
(defn nth-permutation [选择(concat(重复( - (计数s)(计数d))0 )d)]
((reduce
(fn [mi]
(let [[left [item& ]($($))
$($)$($)$($)$($)让我们来试试:a。b:b:b:b:b:b:b:b:b:b: (def colors [redbluegreenyellowcyanmagentablack white])
(nth-permutation colors 39038)
=> [whitemagentabluegreencyanyellowredblack]
...在问题中,但不产生任何其他排列。
很好,但是我们能得到它们吗? >
(def x(map(partial nth-permutation colors)(range(nth factorial(count colors))))
(count x)
=> 40320
(count(distinct x))
=> 40320
(nth factorial(count colors))
=> 40320
请注意,排列是按照(按索引按字典顺序)生成的:
user => (pprint(take 24 x))
([redbluegreenyellowcyanmagentablackwhite]
[red greenyellowcyanmagentawhiteblack]
[redbluegreen b $ b [红色蓝色绿色黄色青色黑色白色洋红色]
[白色品红色黑色]
[红色蓝色绿色黄色青色白色 greenyellowmagentacyangreenmagentacyanblackwhite]
[redbluegreen b $ b [redbluegreenyellowmagentablackcyanwhite]
[黑色白色青色]
[红色蓝色绿色黄色洋红色白色 greenyellowmagentawhiteblackcyan]
[redbluegreenyellowblack b $ b [redbluegreenyellowblackcyanwhitemagenta]
[redbluegreenyellowblack品红色青色白色]
[红色蓝色绿色黄色黑色洋红色 greenyellowblackwhitemagentagrey]
[redbluegreen b $ b [红色蓝色绿色黄色白色青色洋红色黑色]
[青色黑色品红色]
[红色蓝色绿色黄色白色洋红色青色黑色]
[ greenyellowwhitemagentablackcyan]
[redbluegreen b $ b [redbluegreenyellowwhiteblackmagentacyan])
I'd like to make some shuffles of sets which will be the same every time my program is run:
This is one way to do it:
(def colours ["red" "blue" "green" "yellow" "cyan" "magenta" "black" "white"])
(defn colour-shuffle [n]
(let [cs (nth (clojure.math.combinatorics/permutations colours) n)]
[(first cs) (drop 1 cs)]))
; use (rand-int 40320) to make up numbers, then hard code:
(def colour-shuffle-39038 (colour-shuffle 39038))
(def colour-shuffle-28193 (colour-shuffle 28193))
(def colour-shuffle-5667 (colour-shuffle 5667))
(def colour-shuffle-8194 (colour-shuffle 8194))
(def colour-shuffle-13895 (colour-shuffle 13895))
(def colour-shuffle-2345 (colour-shuffle 2345))
colour-shuffle-39038 ; ["white" ("magenta" "blue" "green" "cyan" "yellow" "red" "black")]
But it takes a while to evaluate, and seems wasteful and rather inelegant.
Is there some way of generating shuffle 39038 directly, without generating and consuming all of the sequence?
(I already realise that I can hard code them, or bring the effort back to compile time with a macro. That also seems a bit rubbish.)
解决方案 Sounds like you want to number permutations:
(def factorial (reductions * 1 (drop 1 (range))))
(defn factoradic [n] {:pre [(>= n 0)]}
(loop [a (list 0) n n p 2]
(if (zero? n) a (recur (conj a (mod n p)) (quot n p) (inc p)))))
(defn nth-permutation [s n] {:pre [(< n (nth factorial (count s)))]}
(let [d (factoradic n)
choices (concat (repeat (- (count s) (count d)) 0) d)]
((reduce
(fn [m i]
(let [[left [item & right]] (split-at i (m :rem))]
(assoc m :rem (concat left right)
:acc (conj (m :acc) item))))
{:rem s :acc []} choices) :acc)))
Let's try it:
(def colours ["red" "blue" "green" "yellow" "cyan" "magenta" "black" "white"])
(nth-permutation colours 39038)
=> ["white" "magenta" "blue" "green" "cyan" "yellow" "red" "black"]
...as in the question, but without generating any of the other permutations.
Well enough, but would we get them all?
(def x (map (partial nth-permutation colours) (range (nth factorial (count colours)))))
(count x)
=> 40320
(count (distinct x))
=> 40320
(nth factorial (count colours))
=> 40320
Note the permutations are generated in (lexicographic by index) order:
user=> (pprint (take 24 x))
(["red" "blue" "green" "yellow" "cyan" "magenta" "black" "white"]
["red" "blue" "green" "yellow" "cyan" "magenta" "white" "black"]
["red" "blue" "green" "yellow" "cyan" "black" "magenta" "white"]
["red" "blue" "green" "yellow" "cyan" "black" "white" "magenta"]
["red" "blue" "green" "yellow" "cyan" "white" "magenta" "black"]
["red" "blue" "green" "yellow" "cyan" "white" "black" "magenta"]
["red" "blue" "green" "yellow" "magenta" "cyan" "black" "white"]
["red" "blue" "green" "yellow" "magenta" "cyan" "white" "black"]
["red" "blue" "green" "yellow" "magenta" "black" "cyan" "white"]
["red" "blue" "green" "yellow" "magenta" "black" "white" "cyan"]
["red" "blue" "green" "yellow" "magenta" "white" "cyan" "black"]
["red" "blue" "green" "yellow" "magenta" "white" "black" "cyan"]
["red" "blue" "green" "yellow" "black" "cyan" "magenta" "white"]
["red" "blue" "green" "yellow" "black" "cyan" "white" "magenta"]
["red" "blue" "green" "yellow" "black" "magenta" "cyan" "white"]
["red" "blue" "green" "yellow" "black" "magenta" "white" "cyan"]
["red" "blue" "green" "yellow" "black" "white" "cyan" "magenta"]
["red" "blue" "green" "yellow" "black" "white" "magenta" "cyan"]
["red" "blue" "green" "yellow" "white" "cyan" "magenta" "black"]
["red" "blue" "green" "yellow" "white" "cyan" "black" "magenta"]
["red" "blue" "green" "yellow" "white" "magenta" "cyan" "black"]
["red" "blue" "green" "yellow" "white" "magenta" "black" "cyan"]
["red" "blue" "green" "yellow" "white" "black" "cyan" "magenta"]
["red" "blue" "green" "yellow" "white" "black" "magenta" "cyan"])
这篇关于我可以在clojure中做一个确定性洗牌吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!