def random_number
t = Time.now.to_f / (Time.now.to_f % Time.now.to_i)
random_seed = t * 1103515245 + 12345;
(random_seed / 65536) % 32768;
end
10.times { puts random_number }
cnt = Array.new(10,0)
20000.times { cnt[(random_number % 10).to_i] += 1 }
p cnt
puts
def gaussian_rand
u1 = u2 = w = g1 = g2 = 0
begin
u1 = 2 * rand - 1
u2 = 2 * rand - 1
w = u1 * u1 + u2 * u2
end while w >= 1
w = Math::sqrt( ( -2 * Math::log(w)) / w )
g2 = u1 * w;
g1 = u2 * w;
end
sum = 0
sumsq = 0
n = 1000
0.upto(n) do
r = gaussian_rand * 100 + 50
sum += r
sumsq += (r*r)
end
ave = sum/n
stddev = Math::sqrt(sumsq/n - ave * ave)
puts "Average = #{ave}"
puts "StdDev = #{stddev}"
puts
IM = 139968
IA = 3877
IC = 29573
$last = 42.0
def gen_random (max) (max * ($last = ($last * IA + IC) % IM)) / IM end
10.times do
puts gen_random(100000.0)
end
printf "%.5f\n", gen_random(100.0)
puts
def box_mueller( mean = 0.0, stddev = 1.0 )
x1 = 0.0, x2 = 0.0, w = 0.0
until w > 0.0 && w < 1.0
x1 = 2.0 * rand - 1.0
x2 = 2.0 * rand - 1.0
w = ( x1 * x2 ) + ( x2 * x2 )
end
w = Math.sqrt( -2.0 * Math.log( w ) / w )
r = x1 * w
mean + r * stddev
end
10.times { puts box_mueller(5.0, 1.0) }
puts
def gen
(x=rand)>0.5 ? x : (x < rand/2.0) ? 1.0 - x : x
end
def gen2
(x = rand) && rand ? 1.0 - x : x
end
def compute_distribution(numSamples, &block)
samples = []
values = 10
numSamples.times{samples << yield}
dist = Array.new(values, 0)
samples.each{ |s| dist[(s*values).floor] += 1 }
dist
end
p compute_distribution(1000){rand}
p compute_distribution(1000){gen}
p compute_distribution(1000) { gen2 }
puts
def rng(m, low, high)
return nil unless high > low && m > low && m < high
u = rand
if u <= (m-low)/(high-low)
r = low+ Math.sqrt(u*(high-low)*(m-low))
else
r = high - Math.sqrt((1.0-u)*(high-low)*(high-m))
end
end
10.times do
puts rng(50.0, 25.0, 75.0)
end
puts
class Range
def rand
return first if exclude_end? && last == first
Kernel::rand(last - first + (exclude_end? ? 0 : 1)) + first
end
end
r1 = -9..9
r2 = -90...100
p r1.rand, r2.rand
r3 = 0..9
num = []
10.times do
num << r3.rand
if num.first.zero? then num.shift; redo end
end
p num
puts num.to_s.to_i
puts
class Array
def shuffle
array = dup
size.downto 2 do |j|
r = rand j
array[j-1], array[r] = array[r], array[j-1]
end
array
end
end
array = (1..50).to_a
10.times { p array.shuffle.first(10) }
class RNG
def num(min=8,max=min+5,iter=1)
return nil unless min.is_a?(Integer) && max.is_a?(Integer) && max > min && iter.is_a?(Integer)
ret = []
stats = Hash.new(0)
digits = Array(0..9).sort_by {rand}
digits_size = digits.size
iter.times do
count = 0
len = min + rand(max-min+1)
ar = []
while count < len
i = rand(digits_size)
random_num = digits.at(i)
stats[random_num] += 1
ar << random_num
digits = digits.sort_by {rand}
count += 1
if count == 1 && ar.first.zero? then ar.shift; stats[0] -= 1; count = 0 end
end
ret << ar.to_s.to_i
end
ret << stats
end
end
puts
min = 8
max = 13
iter = 10000
result = RNG.new.num(min, max, iter)
stats = result.pop
t = 0
stats.each_value { |v| t += v }
n = 0
t = t * 1.0
m = t / 10.0
stats.sort.each do |k,v|
i = (v / t) * 100.0
x = v > m ? v - m : m - v
y = (x / m) * 100.0
n += i
puts "#{k} :: #{"%.2f" % m} :: #{v} :: #{"%.2f" % i} % :: #{ "%.2f" % ((m-v) * -1) } :: #{"%.2f" % y} %"
end
puts n, m, t
puts
puts RNG.new.num(20, 25, 10)[0..-2]
puts
rn = RNG.new.num(80, 100)
puts rn[0..-2]
p rn.last