Pseudo-randomize an array in a consistent order

Here’s my final version in case anyone’s interested:

class Array

def randomize!(seed=nil)
srand(seed) if seed
i = length - 1
while (i > 0)
#have to specify Kernel::rand to avoid method name clash
j = Kernel::rand(i)
# Swap self[i] and self[j]
tmp = self[i]
self[i] = self[j]
self[j] = tmp
i -= 1
end
#reset srand
srand if seed
self
end

def randomize(seed=nil)
self.dup.randomize!(seed)
end

end

I encountered a puzzling gotcha with rand - it turns out that Rails
monkey-patches Array with ‘rand’ (no arguments) which pulls out a random
element. So, calling

j = rand(i)

was giving me a ‘too many arguments’ error, as it thought i was wanting
Array::rand. So, i just specify that i want Kernel::rand and it’s fine.

thanks again
max

On Fri, 4 Jul 2008, Max W. wrote:

  # Swap self[i] and self[j]

def randomize(seed=nil)
self.dup.randomize!(seed)
end

end

I don’t think it randomizes very well.

1000.times { puts “yes!” if [1,2].randomize == [1,2] }
=> 1000

I encountered a puzzling gotcha with rand - it turns out that Rails
monkey-patches Array with ‘rand’ (no arguments) which pulls out a random
element.

I’d describe that as a gotcha with Rails :slight_smile:

David

David A. Black wrote:

I don’t think it randomizes very well.

1000.times { puts “yes!” if [1,2].randomize == [1,2] }
=> 1000
David

Well spotted - this is the offending line:

j = Kernel::rand(i)

It means (effectively) that a number can never stay in the same place,
which breaks the randomness a bit (and totally breaks it for two-element
arrays). Changing it to this

j = Kernel::rand(i+1)

seems to fix it.

thanks!
max

It means (effectively) that a number can never stay in the same place,

Err by ‘number’ i mean ‘element’ of course (elements just happen to be
numbers in the example).