in reply to generating random numbers within a range

$seed and $rand are indexes into @range, but @range changes so you need to get the value at that index.

use strict; use warnings; my $low = 1; my $high = 10; my @range=($low .. $high); my $rand=$range[rand(@range)]; # <--- my $seed=$low-1; # <--- Works for all values of $low + and $high. my $count=1; my $lastguess; while ( $seed != $rand ) { #undef @range if ( $ count > 1); # <--- Useless. @range=($low .. $high); $lastguess = $seed; $seed = $range[rand(@range)]; # <--- if ( $seed < $rand ) { print "You're too low - $seed (last guess = $lastguess)\n"; $low=$seed+1; $count++; } elsif ( $seed > $rand ) { print "you're too high - $seed (last guess = $lastguess)\n"; $high=$seed-1; $count++; } } print "you got it in $count tries\n"; print "seed = $seed rand = $rand ( last guess = $lastguess )\n";

Added: As a bonus, here's cleaner code and output:

use strict; use warnings; my $low = 1; my $high = 10; my $range = $high - $low + 1; my $rand = $low + int(rand($range)); my $count = 0; for (;;) { my $guess = $low + int(rand($range)); $count++; print("$count) Guessing $guess."); last if $guess == $rand; if ( $guess < $rand ) { print " Too low.\n"; $low = $guess + 1; } elsif ( $guess > $rand ) { print " Too high.\n"; $high = $guess - 1; } $range = $high - $low + 1; } if ($count == 1) { print " Got it on the first try!\n"; } else { print " Got it in $count tries.\n"; }

It's "cleaner" because (1) a list (@range) isn't built where one isn't needed, (2) $count is updated when a guess is actually made, (3) $seed is more appropriately called $guess, and (4) $seed isn't checked against $guess until a guess is actually made. Also, (5) I removed the previous guess from the output, since (A) it would need to be omitted on the first guess, and (B) the previous guess is already displayed on the previous line.

Replies are listed 'Best First'.
Re^2: generating random numbers within a range
by tcf03 (Deacon) on May 09, 2005 at 19:40 UTC
    Thanks! Its a time waster, but it was driving me nuts...
    Ted
    --
    "Men have become the tools of their tools."
      --Henry David Thoreau

      By the way, if you want to guess the number in a guaranteed maximum number of guesses, divide the search space into two instead of randomly guessing.
      Change
      my $guess = $low + int(rand($range));
      to
      my $guess = $low + int($range/2);
      to see this in action. You'll find the number of guesses is never more than ceil(log2(range)) guesses. This is called a binary search.

      ceil(log2(x)) ------------- 1.. 8: 3 1.. 16: 4 1.. 32: 5 1.. 64: 6 1.. 128: 7 1.. 256: 8 1.. 512: 9 1.. 1024: 10 1.. 10: 4 1.. 100: 7 1.. 1,000: 10 1.. 10,000: 14 1.. 100,000: 17 1.. 1,000,000: 20 1..10,000,000: 24
        Very cool - Thats more along the lines of what humans would do. I like that one.
        Ted
        --
        "Men have become the tools of their tools."
          --Henry David Thoreau