Array.shuffle/Array.shuffle!

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...

···

--
Posted via http://www.ruby-forum.com/.

Jeff Moore 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 }

···

--
RMagick: http://rmagick.rubyforge.org/

Jeff Moore 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)

···

--
Posted via http://www.ruby-forum.com/\.

Tim Hunter wrote:

Jeff Moore 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 }

"Gone in 60 seconds"...

Thanks

···

--
Posted via http://www.ruby-forum.com/\.

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

···

On Sun Aug 24 19:17:11 2008, Stefan Rusterholz wrote:

which for many cases probably still is faster in ruby since it runs
mainly in C, I didn't bench it, though

--
Fred O. Phillips

BBC7 7572 755F 83E0 3209 504A E4F7 874F 1545 9D41

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.

···

--
Posted via http://www.ruby-forum.com/\.

Jeff Moore 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.

···

--
       vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407

No, 'I' is next in line. "Irresponsible Irmin"

Joel VanderWerf wrote:

···

Jeff Moore 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.

--
Posted via http://www.ruby-forum.com/\.