我可以在clojure中做一个确定性洗牌吗? [英] Can I make a Deterministic Shuffle in clojure?

查看:176
本文介绍了我可以在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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆