Never been to DZone Snippets before?

Snippets is a public source code repository. Easily build up your personal collection of code snippets, categorize them with tags / keywords, and share them with the world

« Newer Snippets
Older Snippets »
Showing 11-20 of 46 total

randomizing an array in ruby (the right way)

Snagged from http://www.rubyquiz.com/quiz113.html

   1  
   2  # be sure to use sort_by rather than sort
   3  quiz = (1..10).to_a
   4  quiz.sort_by { rand }

Api key (or any kind of key) generator

Generates a random key for API neatness.

   1  
   2  class KeyGenerator
   3    require "digest/sha1"
   4    def self.generate(length = 10)
   5      Digest::SHA1.hexdigest(Time.now.to_s + rand(12341234).to_s)[1..length]
   6    end
   7  end

Weighted Random array selection

Say you have an array of ['apples', 'oranges', 'bananas', 'kiwis']

Selecting a random item is simple enough
   1  
   2    arr = ['apples', 'oranges', 'bananas', 'kiwis']
   3    arr[rand(arr.size)]


But say you want to have apples come up 50% of the time, oranges 25%, bananas 15% and kiwis 10% ...


   1  
   2    class Array
   3      
   4      #sum (and mean) found on http://snippets.dzone.com/posts/show/2161
   5      def sum
   6        inject( nil ) { |sum,x| sum ? sum+x : x }
   7      end
   8      
   9      def probability(spread = 2)
  10        z = 1.0
  11        collect {|x| z = z / spread}
  12      end
  13      def weighted_random_index(probability_array = probability(2) )
  14        size.times do |x|
  15          return x if rand < probability_array[0..x].sum
  16        end
  17        return 0
  18      end
  19      
  20      def get_weighted_random_item(probability_array = probability(2))
  21        self[weighted_random_index(probability_array)]
  22      end
  23      
  24      def get_weighted_random_indexes(num_items, p = probability(2))
  25        res = []
  26        escape = 1000
  27        while res.size < num_items and escape > 0
  28          escape -= 1
  29          tmp = weighted_random_index(p) 
  30          res << tmp unless res.include?(tmp)
  31        end
  32        return res.sort
  33      end
  34    
  35    end
  36  
  37  
  38  arr = ['apples', 'oranges', 'bananas', 'kiwis']
  39  10.times do |i|
  40    puts arr.get_weighted_random_item([0.5, 0.25, 0.15, 0.10])
  41  end
  42  
  43  oranges
  44  oranges
  45  apples
  46  apples
  47  bananas
  48  apples
  49  apples
  50  bananas
  51  oranges
  52  apples
  53  


I'm sure there's some math term for this but I'm calling it 'spread' until I learn otherwise. I put in a default probability array of p = p / 2 which gives you (for an array of 4)

   1  
   2  arr.probability
   3  => [0.5, 0.25, 0.125, 0.0625]


On larger arrays the probabilities will get (for all practicle purposes) zero quickly

   1  
   2  arr = [1,2,3,4,5,6,7,8,9]
   3  => [1, 2, 3, 4, 5, 6, 7, 8, 9]
   4  arr.probability
   5  => [0.5, 0.25, 0.125, 0.0625, 0.03125, 0.015625, 0.0078125, 0.00390625, 0.001953125]


I put in a simple spread concept to spread out the probabilities a bit more... the higher the spread, the more even the probability distribution (this varies a lot with array size - but here's a simple example):

   1  
   2     arr = ['apples', 'oranges', 'bananas', 'guava']
   3     iterations = 10000
   4     4.times do |t|
   5       p = arr.probability(t+2)
   6       res = Array.new(arr.size).fill(0)
   7       iterations.times do |x|
   8         res[arr.weighted_random_index(p)] += 1
   9       end
  10       res2 = res.collect {|x| (x/iterations.to_f) * 100}
  11       puts "For probability spread #{t+2}"
  12       puts "Results #{res2.join(", ")} = #{res2.sum}"
  13       puts ""
  14     end
  15  
  16     For probability spread 2
  17     Results 49.71, 37.55, 11.35, 1.39 = 100.0
  18  
  19     For probability spread 3
  20     Results 43.44, 29.99, 17.79, 8.78 = 100.0
  21  
  22     For probability spread 4
  23     Results 48.3, 23.56, 16.73, 11.41 = 100.0
  24  
  25     For probability spread 5
  26     Results 54.22, 19.31, 14.65, 11.82 = 100.0


Here is a longer example:

   1  
   2      def weighted_random_index_example
   3        arr = ['apples', 'oranges', 'bananas', 'guava']
   4        puts "Sample array = [#{arr.join(",")}]"
   5        p = [0.5,0.25, 0.15, 0.10]
   6        puts "Probability that each will show up [#{p.join(', ')}]"
   7        puts "1000 runs..."
   8        res = Array.new(arr.size).fill(0)
   9        1000.times do |t|
  10          res[arr.weighted_random_index(p)] += 1
  11        end
  12        res2 = res.collect {|x| (x/1000.0) * 100}
  13        puts "Results:"
  14        4.times do |t|
  15          puts "    #{arr[t]}: #{res2[t]}%"
  16        end
  17        
  18        puts ""
  19        puts "You can also use more spread out probability arrays"
  20        p = arr.probability(3)
  21        puts "Probability that each will show up with a spread of 3 [#{p.join(', ')}]"
  22        puts "1000 runs..."
  23        res = Array.new(arr.size).fill(0)
  24        1000.times do |t|
  25          res[arr.weighted_random_index(p)] += 1
  26        end
  27        res2 = res.collect {|x| (x/1000.0) * 100}
  28        puts "Results:"
  29        4.times do |t|
  30          puts "    #{arr[t]}: #{res2[t]}%"
  31        end
  32        
  33        puts ""
  34        puts "You can also just get selected indexes"
  35        puts "arr.get_weighted_random_indexes(3,p) = [#{arr.get_weighted_random_indexes(3,p).join(', ')}]"
  36        
  37        puts "The probability spread will depend on the number of items in your array - for an array of 4 it looks like this:"
  38        8.times do |t|
  39          puts "  probability(#{t+2}):  [#{arr.probability(t+2).collect {|x| sprintf('%0.5f',x)}.join(', ')}]"
  40        end
  41        return nil
  42      end
  43      weighted_random_index_example
  44  
  45  Outputs...
  46  Sample array = [apples,oranges,bananas,guava]
  47  Probability that each will show up [0.5, 0.25, 0.15, 0.1]
  48  1000 runs...
  49  Results:
  50      apples: 49.1%
  51      oranges: 38.3%
  52      bananas: 11.3%
  53      guava: 1.3%
  54  
  55  You can also use more spread out probability arrays
  56  Probability that each will show up with a spread of 3 [0.333333333333333, 0.111111111111111, 0.037037037037037, 0.0123456790123457]
  57  1000 runs...
  58  Results:
  59      apples: 43.6%
  60      oranges: 29.2%
  61      bananas: 18.0%
  62      guava: 9.2%
  63  
  64  You can also just get selected indexes
  65  arr.get_weighted_random_indexes(3,p) = [0, 1, 3]
  66  The probability spread will depend on the number of items in your array - for an array of 4 it looks like this:
  67    probability(2):  [0.50000, 0.25000, 0.12500, 0.06250]

Ruby dictionary username generation

Generate a new random name from dictionary words.

   1  
   2  DICT_PATH = '/usr/share/dict/words'
   3  DICT_SIZE = 234936
   4  
   5  def self.generated_name words = 2, length = 23
   6    name = 'a'*(length+1)
   7    while name.length > length
   8      name = (1..words).map{%x[sed -n '#{rand(DICT_SIZE)} {p;q;}' '#{DICT_PATH}'].chomp.capitalize}.join
   9    end
  10  end

C++ way to randomly select M numbers

This will randomly select M numbers from the interval [1, NMAX].

Note the extensive use of STL.

   1  
   2  const short NMAX = 49;
   3  const short M = 6;
   4  
   5  std::vector<short> v;
   6  for (short i(0); i < NMAX; ++i)
   7  	v.push_back(i + 1);
   8  
   9  random_shuffle(v.begin(), v.end());
  10  copy(v.begin(), v.begin() + M, std::ostream_iterator<short>(std::cout, " "));

Generate a random string of letters

// Generates a random string of lowercase letters. Great for email verification codes ;)

   1  
   2  Array.new(6) { (rand(122-97) + 97).chr }.join

Generate a random string of letters

// Generates a random string of lowercase letters. Great for email verification codes ;)

   1  
   2  Array.new(6) { (rand(122-97) + 97).chr }.join

Generate a random string of letters

// Generates a random string of lowercase letters. Great for email verification codes ;)

   1  
   2  Array.new(6) { (rand(122-97) + 97).chr }.join

Generate a random string of letters

Generates a random string of lowercase letters. Great for email verification codes ;)

   1  
   2  Array.new(6) { (rand(122-97) + 97).chr }.join

Generate a random string of letters

Generates a random string of lowercase letters. Great for email verification codes ;)

   1  
   2  Array.new(6) { (rand(122-97) + 97).chr }.join
« Newer Snippets
Older Snippets »
Showing 11-20 of 46 total