module Enumerable
def shuffle3
h = Hash.new
k = rand(1000000000)
self.each do |v|
k = rand(1000000000) until !h.has_key?(k)
h[k] = v
end
h.keys.sort.collect { |k| h[k] }
end
def shuffle4
h = {}
k = rand(1000000000)
self.sort_by{ k = rand(1000000000) while h.has_key?(k); h[k] = k }
end
end
What you have posted does not avoid collisions.
You probably mean something like
a.sort {2*rand(12345) <=> 2 * rand(12345) + 1}
However, the problem of the sort {rand<=>rand}
methods are not collisions, but the skewed results
from the algorithm that assumes a consistent
comparison operator. Quoting from an earlier
post of mine:
ar = [0, 1, 2]; result = Hash.new(0)
100000.times {result[ar.sort {rand <=> rand}] += 1}
p result
def shuffle(a):
b = [ (random(), i) for i in a]
b.sort()
return [ x[1] for x in b ]
print shuffle(range(10))
I would have thought those two functions do the same thing
with the exception that shuffle does not sort in place.
I’m probably missing something obvious. Could you explain
the difference between the two versions?