Qwertie
Qwertie

Reputation: 6493

Generate a random number with a seed between a range in ruby

I'm trying to get the banner image on my website to change once a day. I can see ruby has srand which will let me input a number for the date and return the same result every time it is called on the same day but this returns a very long number. I also saw rand lets me use a range like rand(a..b).

Is there any way I can use srand with a range like I can with rand?

Upvotes: 4

Views: 2208

Answers (3)

Stefan
Stefan

Reputation: 114158

You could use the date's Julian day number as the seed:

require 'date'
Date.new(2017, 6, 1).jd #=> 2457906
Date.new(2017, 6, 2).jd #=> 2457907
Date.new(2017, 6, 3).jd #=> 2457908

This can then be used to generate a random daily index:

def number_of_banners
  10
end

def daily_banner_index(date = Date.today)
  Random.new(date.jd).rand(number_of_banners)
end

daily_banner_index
#=> 8

Or a random daily element from an array:

def banners
  %w(foo_banner bar_banner baz_banner)
end

def daily_banner(date = Date.today)
  banners.sample(random: Random.new(date.jd))
end

daily_banner
#=> "bar_banner"

Upvotes: 2

pjs
pjs

Reputation: 19855

You can create a special/designated random number generator with any seed value you like:

special = Random.new 42 # create a new instance of Random seeded with 42
20.times { p special.rand(5..10) } # generate 20 random ints in range 5 to 10

Your special instance of Random is independent of kernel#rand unless you use srand to initialize it with the same seed value.

Upvotes: 6

Qwertie
Qwertie

Reputation: 6493

To avoid breaking the random number generator for the rest of my application I went with

(Date.today.to_s.gsub('-','').to_i) % number_of_banners

While not exactly random it should work well enough for this case but I would be interested in better solutions.

Upvotes: 0

Related Questions