Random Number within a range(exclude some numbers)

PHP programming forum. Ask questions or help people concerning PHP code. Don't understand a function? Need help implementing a class? Don't understand a class? Here is where to ask. Remember to do your homework!

Moderator: General Moderators

Post Reply
lepass_7
Forum Newbie
Posts: 7
Joined: Wed Apr 02, 2008 5:15 am

Random Number within a range(exclude some numbers)

Post by lepass_7 »

Hi guys, i would like to produce random numbers using php the numbers in a range must be unique. For example i have 11 numbers:
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10.
The first time i click on the CREATE_NUMBER the function will return (random) a number lets say(for example) it returns the number 2. The second time i click on the CREAT_NUMBER i want the range of numbers will be: 0, 1, 3, 4, 5, 6, 7, 8, 9, 10 (without the number 2). Lets say the second click returns the number 6, so the remaining numbers will be: 1, 3, 4, 5, 7, 8, 9, 10. At the end i ll take a random sequence of numbers for example:

2, 6, 3, 8, 4, 1, 9, 5, 10, 9, 7, 0.
At the twelfth click i would like the restart of the function using all the numbers.
I wrote some code and works but i dont think is very good solution:

Code: Select all

$counter=mysql_num_rows($data);
        
$random=mt_rand(0,$counter-1);
$exclude=explode(';',$_SESSION['numbers']);
$sizeof_exclude=count($exclude);
            
if($sizeof_exclude<=$counter-1)
{
    while(in_array($random,$exclude))
    {
        $random=mt_rand(0,counter-1);
    }
}
else
{
    session_unset();
        //restart function
}
echo $random;
$_SESSION['numbers']=$_SESSION['numbers'].$random.';';

EXPLANATION: I count the rows of a mysql query and i store it in a counter($counter) , next i create a random number between 0 and $counter-1 and i store it($random). Next using the global $_SESSION i get the numbers that already have been produced and store them in an $exclude array. Next i count the size of the exclude array($sizeof_exclude). Next i use the "if" so i can decide if all the numbers are produced so if NOT i proceed to produce a new one random number, using this logic i get "stuck" on a while loop creating random numbers until a the new random numbers NOT exist in the exclude array. Thats it.

The problem with that algorithm is: If the $counter is a big number at some time the while loop it will looping for a long time until it finds the new unique random number, for example if $counter=1000 and i have already produce 999 unique random numbers and i am looking for the 1000th unique random number (for example is 26) so the loop practically it will loop forever(theoretically sometime will find the 26).

Any other ideas?????
User avatar
pickle
Briney Mod
Posts: 6445
Joined: Mon Jan 19, 2004 6:11 pm
Location: 53.01N x 112.48W
Contact:

Re: Random Number within a range(exclude some numbers)

Post by pickle »

Some array functions would work well:

Code: Select all

$counter = mysql_num_rows($data);
$values = range(0,$counter);
$random = array_rand($values);
unset($values[$random]);
$values will then only contain numbers that haven't been chosen. You can store that in $_SESSION.
Real programmers don't comment their code. If it was hard to write, it should be hard to understand.
User avatar
VladSun
DevNet Master
Posts: 4313
Joined: Wed Jun 27, 2007 9:44 am
Location: Sofia, Bulgaria

Re: Random Number within a range(exclude some numbers)

Post by VladSun »

Another approach:

Code: Select all

// Run once
$counter = 10;
$values = range(0, $counter);
shuffle($values);
 
 
//Run $counter times
echo $values[--$counter]." ";
Though, I like pickle's solution more than mine :)
There are 10 types of people in this world, those who understand binary and those who don't
lepass_7
Forum Newbie
Posts: 7
Joined: Wed Apr 02, 2008 5:15 am

Re: Random Number within a range(exclude some numbers)

Post by lepass_7 »

Hey guys thnxs both of you for your quick replies. I agree with you VladSun so i used pickle logic and it worked:

Code: Select all

 
$counter=mysql_num_rows($data);
            //echo "<br />COUNTER :".$counter."<br />";
            //*****************************
            $values=$_SESSION['numbers'];
            if($_SESSION['numbers']==null)
            {
                
                $values = range(1,$counter);
            }
            $random = array_rand($values);
            echo ($counter-count($values)+1).' from ';
            echo $counter;
            
            $id=$values[$random];
if(count($values)>=0)
            {
                
                echo $id;
            }
            else
            {
                session_unset();
            }
            unset($values[$random]);
            $_SESSION['numbers']=$values;
 
By the way i had another idea, so i would like to share it with you:

The whole idea is the first time i ll creat an array using $values=range(1,$counter) next i ll randomize the array -->shuffle($values) and store it in the SESSION i also store a $counter in the SESSION starting from zero, so my new random number will be $values[$counter]. Take a look:

Code: Select all

 
$counter=mysql_num_rows($data);
$values=$_SESSION['numbers'];
            if($_SESSION['numbers']==null)
            {
                //the first time 
                $values = range(1,$counter);
                shuffle($values);
            }
            if($_SESSION['counter']==null)
            {
                $_SESSION['counter']=0;
            }
            $id=$values[$_SESSION['counter']];
            echo $_SESSION['counter'].' from ';
            echo $counter;
            
            
            if($counter>$_SESSION['counter'])
            {
                echo $id
            }
            else
            {
                session_unset();
                
            }
            
            unset($values[$random]);
            $_SESSION['numbers']=$values;   
            $_SESSION['counter']=$_SESSION['counter']+1;
 
What do you think?Is this idea better? Or use pickle code?
Thnxs in advance!
Post Reply