我有一个存储一些名字的数组。每个人都解决了一项任务,然后我想将每个解决方案分配给不同的人进行验证。简而言之,这意味着我需要以一种没有元素保持其原始位置的方式在数组中执行shuffle。我想到的解决方案是在数组中执行shuffle,直到满足第二个条件,这里是代码:
copied = names.dup
loop do
copied.shuffle!
valid = true
(0...copied.size).each do |i|
if copied[i] == names[i]
valid = false
break
end
end
break if valid
end
puts copied
我仍然觉得这个问题可能有更优化的解决方案。任何人都有更好的主意吗?
答案 0 :(得分:3)
您尝试做的就是创建{verifier => task_solver}
verifier != task_solver
的地图。实现这一目标的一个简单方法就是让每个人都验证下一个人的任务:
verifiers = {}
task_solvers.each_with_index do |task_solver, index|
verifiers[task_solver] = task_solvers[(index + 1) % task_solvers.size]
end
如果你想要更多随机化,你可以使用它,它使用相同的算法,但只是在发生任何事情之前洗牌你的列表:
verifiers = {}
shuffled_task_solvers = task_solvers.shuffle
shuffled_task_solvers.each_with_index do |task_solver, index|
verifiers[task_solver] = shuffled_task_solvers[(index + 1) % shuffled_task_solvers.size]
end
答案 1 :(得分:2)
你所追求的可能被称为紊乱。看看这里:http://rosettacode.org/wiki/Permutations/Derangements(Ruby中有一个例子)。
答案 2 :(得分:1)
我认为你只需要一次洗牌。之后,如果复制数组中的某些元素位于其原始位置,则可以将其与其中一个邻居交换(很明显,这两个元素的新位置不能与原始位置相同)。
答案 3 :(得分:1)
这是我想出的。我不知道它是否更好:P
list = [1,2,3,4,5,6,7,8]
def jumble (array)
new = array.shuffle
array.each_with_index do |item, index|
if new[index] == item
new[index], new[index - 1] = new[index - 1], new[index]
end
end
new
end
new = jumble (list)
puts new.inspect
输出:
[4, 1, 8, 3, 7, 2, 6, 5]