def shuffle arr
shuffled = []
while arr.length > 0
randNum = rand(arr.length)
idx = 0
unshuf = []
print '--- arr='; p arr # <--------
arr.each do |item|
if idx == randNum
shuffled.push item
else
unshuf.push item
end
print 'shuffled='; print shuffled; print ', unshuf='; p unshuf # <--------
idx = idx + 1
end
arr = unshuf
end
return shuffled
end
p shuffle([ 11, 12, 13, 14, 15])
Execution :
$ ruby -w t.rb
--- arr=[11, 12, 13, 14, 15]
shuffled=[], unshuf=[11]
shuffled=[], unshuf=[11, 12]
shuffled=[13], unshuf=[11, 12]
shuffled=[13], unshuf=[11, 12, 14]
shuffled=[13], unshuf=[11, 12, 14, 15]
--- arr=[11, 12, 14, 15]
shuffled=[13, 11], unshuf=[]
shuffled=[13, 11], unshuf=[12]
shuffled=[13, 11], unshuf=[12, 14]
shuffled=[13, 11], unshuf=[12, 14, 15]
--- arr=[12, 14, 15]
shuffled=[13, 11, 12], unshuf=[]
shuffled=[13, 11, 12], unshuf=[14]
shuffled=[13, 11, 12], unshuf=[14, 15]
--- arr=[14, 15]
shuffled=[13, 11, 12, 14], unshuf=[]
shuffled=[13, 11, 12, 14], unshuf=[15]
--- arr=[15]
shuffled=[13, 11, 12, 14, 15], unshuf=[]
[13, 11, 12, 14, 15]
Explanation : the content of arr is randomly distributed between shuffled and unshuf. Then unshuf replaces arr and, if there was something in unshuf, the while loop redistributes randomly a little in shuffle, a little in unshuf. And so on until unshuf is empty. So shuffled is progressively filled with elements randomly taken from the parameter arr initially given to the method shuffle, but arr is also progressively emptied by keeping only unshuf elements in arr = unshuf. Of course after having been moved into arr, unshuf must be reset to an empty array to receive the new distribution, while shuffled must keep growing. Hope it's clear.
unshuf = []repoints the label 'unshuf' at a new, empty, array. it has no effect on the object formerly referenced byunshuf