如何编写一个带有名称列表并分配每个名称的函数 命名另一个名称,但名称不能相同。
这是我走了多远:
(def people
'("Peter" "Steve" "Mikel" "Andrea" "Hans" "Oliver" "Greg"))
(defn assign-people []
(let [perm (map hash-map people (shuffle people))]
perm))
此函数产生例如:
({Peter Hans} {Steve Mikel} {Mikel Andrea} {Andrea Greg} {Hans Steve} {Oliver Oliver} {Greg Peter})
如何防止将名称分配给自己?
编辑:还应注意,没有名称被分配两次或更多次但只分配一次
答案 0 :(得分:4)
可能是
(let [rand (shuffle people)
second (rest (cycle rand))
result (map vector rand second)]
result)
它的作用 - 只是生成一个随机序列,然后循环自身并移动1.因此对于长度为>的每个列表。 1它保证元素不匹配。
结果是一个矢量列表,但不确定它是否适合您的任务。如果是 - 您肯定可以将结果形状更改为您想要的任何内容。
例如,要获取哈希映射列表:
(let [rand (shuffle people)
second (rest (cycle rand))
result (map hash-map rand second)]
result)
答案 1 :(得分:1)
我们可以保留shuffle
,直到我们得到没有匹配的答案:
(defn derange [s]
(loop []
(let [cand (shuffle s)]
(if (not-any? identity (map = cand s))
cand
(recur)))))
(derange people)
;["Hans" "Greg" "Andrea" "Peter" "Steve" "Mikel" "Oliver"] ; for example
使用相等的值替换值不会令人满意。如果我们想要一个随机排列,无论它是否改变每个值,我们都可以解开索引:
(defn derange [s]
(let [v (vec s), nos (-> s count range vec)]
(loop []
(let [cand (shuffle nos)]
(if (not-any? identity (map = cand nos))
(map v cand)
(recur))))))
(derange (repeat 5 \a))
;(\a \a \a \a \a)
答案 2 :(得分:0)
鉴于n是人数,即:n = (count people)
:
(->> (cycle people) (partition 2) (take n))
如果您需要将对存储在哈希映射中,则可以在获取后添加(map #(apply hash-map %))
。如果你每次都需要一个随机的结果,你可以先给人们洗牌:
(->> (shuffle people) cycle (partition 2) (take n))