Random Number Generator

Posted by blackhole82 on 2009-10-17 10:29

I'm trying to generate random numbers in a sequence that are not repeated, however it appears to be getting stuck in my while loop but I do not know why. Here is my code:

puts -nonewline "Enter lower bound: "
flush stdout;
set lowerBound [gets stdin]
puts -nonewline "Enter upper bound: "
flush stdout;
set upperBound [gets stdin]
puts "The lower bound is: \$lowerBound"
puts "The upper bound is: \$upperBound"
set range [expr {\$upperBound - \$lowerBound}]
puts "The range is: \$range"
set random [expr {floor((rand() *\$range) + \$lowerBound)}]

#Check to see if numberList exists and if so delete it
if {[info exists numberList]} {
unset numberList
}

#Insert random number into list
lappend numberList \$random

#Create list of random numbers in range
for {set i 0} {\$i < \$range} {incr i} {
set random [expr {floor((rand() *\$range) + \$lowerBound)}]
#keep generating random numbers in range until not found in list
while {[lsearch \$numberList \$random] != -1} {
#puts "\$random is repeated"
set random [expr {floor((rand() *\$range) + \$lowerBound)}]
}
lappend numberList \$random
}

puts "Number list: \$numberList"

I'm searching my list to see if the number is already there, if it is, I want to generate another random number until it's not found in the list. The only thing that I can think is that the rand() function is generating the same number over and over again inside the loop... Which it shouldn't be, but I don't know exactly how the random number between 0 and 1 is calculated. If I use it outside a loop it works but does repeat a lot if my range is small.

jeffh
ActiveState Staff
Mon, 2009-10-19 10:28

You should use lsearch -real to ensure you do not default to glob style matching. You may not have an endless loop, just a (worse than) quadratic algorithm. You want to generate a list, but each number you add is randomly being generated against the growing list of numbers. You are lucky to get the last number in as it has a (n-1)/n chance of picking an existing number in the list.

Instead you should create a list of all the data you want, then just randomize that list. Check out http://wiki.tcl.tk/941 for many approaches with discussion.