Random Number Generator

Posted by blackhole82 on 2009-10-17 11: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 11: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.