shuffle in Array


# Timing different way to shuffle an array in ruby

class Array

  # The ruby way of swapping two variable values

  def swap!(a,b)
    self[a], self[b] = self[b], self[a]
  end


  # the "assembler" way of swapping two variable
values

 
def swap_with_int_var!(a,b)
    c = self[a]
    self[a] = self[b]
    self[b] = c
  end


  # Shuffling arrays is usually done by iterating through the
indices, and swapping
  # each value with a value at a random position

  # shuffling based on push/delete

 
def shuffle!
    size.downto(1) { |n| push delete_at(rand(n)) }
    self
  end


  # shuffling with the ruby way of swapping

 
def shuffle_II
    (size-1).downto(1) { |n| swap!(n, rand(size)) }
    self
  end


  # shuffling with the "assembler" way of swapping

 
def shuffle_III
    (size-1).downto(1) { |n| swap_with_int_var!(n, rand(size)) }
    self
  end



 
def shuffle_IV
    sort_by { rand }
  end

                                                           
 
def shuffle_V
    (length - 1).downto 1 do |slot|
      source = rand(slot + 1)
      self[slot], self[source] = self[source], self[slot]
    end
    self
  end
end



def time_shuffle_method(size)
  a = (0..size).to_a

  start_time = Time.new
  3000.times { yield a }
  end_time = Time.new

  return end_time - start_time
end


# To inspect shuffling methods, invoke with argument "test"
and optionally, size

if (ARGV[0] == 'test')                                      
  size =  ARGV[1] ? ARGV[1].to_i : 5
  puts (0..size).to_a.shuffle!
  puts '--'
  puts (0..size).to_a.shuffle_II
  puts '--'
  puts (0..size).to_a.shuffle_III
  puts '--'
  puts (0..size).to_a.shuffle_IV
  puts '--'
  puts (0..size).to_a.shuffle_V

  exit
end


shuffle_time = time_shuffle_method(500) { |a| a.shuffle! }
puts "Time elapsed for shuffle!    : #{shuffle_time}"

shuffle_time_II = time_shuffle_method(500) { |a| a.shuffle_II }
puts "Time elapsed for shuffle_II  :
#{shuffle_time_II}"

shuffle_time_III = time_shuffle_method(500) { |a| a.shuffle_III
}
puts "Time elapsed for shuffle_III : #{shuffle_time_III}"

shuffle_time_IV = time_shuffle_method(500) { |a| a.shuffle_IV }
puts "Time elapsed for shuffle_IV  :
#{shuffle_time_IV}"

shuffle_time_V  = time_shuffle_method(500) { |a| a.shuffle_V  }
puts "Time elapsed for shuffle_V   : #{shuffle_time_V
}"

=begin

  Here are results from running on my machine

  Conclusion: fancy ruby manipulations take their time
  Stick with the "ordinary" shuffle implementation
( shuffle_III )

stephan@[~/ruby/steam]: ruby /tmp/shuffle_timer
Time elapsed for shuffle!    : 4.352824
Time elapsed for shuffle_II  : 6.03016
Time elapsed for shuffle_III : 3.088946
Time elapsed for shuffle_IV  : 3.890105
Time elapsed for shuffle_V   : 6.351477
stephan@[~/ruby/steam]: ruby /tmp/shuffle_timer
Time elapsed for shuffle!    : 4.382251
Time elapsed for shuffle_II  : 6.046666                     
Time elapsed for shuffle_III : 3.220461
Time elapsed for shuffle_IV  : 4.00079
Time elapsed for shuffle_V   : 6.292253

=end

你可能感兴趣的:(java,C++,c,C#,Ruby)