This works but I can’t escape the nagging sense that there’s a more
concise approach (for one thing, it looks like there are way too
transient objects to me).
Anyone have a better idea?
class Array
def shuffle
t_self = self.dup
t_size = self.size
result=[]
t_size.times { result << t_self.slice!(rand(t_self.size)) }
result
end
def shuffle!
t_self = self.dup
t_size = self.size
self.clear
t_size.times { self << t_self.slice!(rand(t_self.size)) }
self
end
end
Regards…
Jeff M. wrote:
This works but I can’t escape the nagging sense that there’s a more
concise approach (for one thing, it looks like there are way too
transient objects to me).
Anyone have a better idea?
ary2 = ary.sort_by { rand }
Jeff M. wrote:
This works but I can’t escape the nagging sense that there’s a more
concise approach (for one thing, it looks like there are way too
transient objects to me).
Anyone have a better idea?
class Array
def shuffle
t_self = self.dup
t_size = self.size
result=[]
t_size.times { result << t_self.slice!(rand(t_self.size)) }
result
end
def shuffle!
t_self = self.dup
t_size = self.size
self.clear
t_size.times { self << t_self.slice!(rand(t_self.size)) }
self
end
end
Regards…
If you need a less predictable one than the sort_by { rand } then I
suggest this:
class Array
Shuffle the array
def shuffle!
n = length
for i in 0…n
r = Kernel.rand(n-i)+i
self[r], self[i] = self[i], self[r]
end
self
end
Return a shuffled copy of the array
def shuffle
dup.shuffle!
end
end
This shuffle is known as fisher-yates/knuth shuffle and is afaik by
current means considered impossible to predict. Also its complexity is
O(n) compared to the O(nlogn) of sort_by (which for many cases probably
still is faster in ruby since it runs mainly in C, I didn’t bench it,
though).
As of 1.8.7 you have those methods already natively provided by ruby.
Regards
Stefan (apeiros)
On Sun Aug 24 19:17:11 2008, Stefan R. wrote:
which for many cases probably still is faster in ruby since it runs
mainly in C, I didn’t bench it, though
Seems you’re right:
Rehearsal -------------------------------------------------------
Knuth: 10.900000 0.000000 10.900000 ( 10.902161)
Sort by #{rand}: 11.050000 0.000000 11.050000 ( 11.060635)
--------------------------------------------- total: 21.950000sec
user system total real
Knuth: 10.930000 0.020000 10.950000 ( 10.946718)
Sort by #{rand}: 11.020000 0.000000 11.020000 ( 11.020902)
require ‘benchmark’
class Array
Shuffle the array
def shuffle!
n = length
for i in 0…n
r = Kernel.rand(n-i)+i
self[r], self[i] = self[i], self[r]
end
self
end
Return a shuffled copy of the array
def shuffle
dup.shuffle!
end
end
n = 500
a = (1…10000).map { rand }
Benchmark.bmbm(20) do |x|
x.report(“Knuth:”) { n.times { a.shuffle } }
x.report(‘Sort by #{rand}:’) { n.times { a.sort_by { rand } } }
end
As of 1.8.7 you have those methods already natively provided by ruby.
Regards
Stefan (apeiros)
Ah! If only the Ubuntu/Debian promotion cycle for Ruby out paced
continental drift…
Thanks again…
I appreciate it.
No, ‘I’ is next in line. “Irresponsible Irmin”
Joel VanderWerf wrote:
Jeff M. wrote:
Ah! If only the Ubuntu/Debian promotion cycle for Ruby out paced
continental drift…
I heard the 9.04 release will be called Galloping Gondwanaland.
Jeff M. wrote:
Ah! If only the Ubuntu/Debian promotion cycle for Ruby out paced
continental drift…
I heard the 9.04 release will be called Galloping Gondwanaland.