0

I'm trying to create a random number generator in PHP. It's supposed to generate three (3) numbers at a time, without repeat. That's to say, the 3 numbers cannot be the same.

Here's what I've tried so far:

$array = [];

$A = mt_rand(1,36);
$array[0] = $A;

$B = mt_rand(1,36);
$array[1] = $B;

if(in_array($B,$array)){
    $B = mt_rand(1,36);
    $array[1] = $B;
}

$C = mt_rand(1,36);
$array[2] = $C;

if(in_array($C,$array)){
    $C = mt_rand(1,36);
    $array[2] = $C;
}

$length = count($array);

//display the array values;

for($i = 0; $i < $length; $i++){
    echo ($array[$i]."<br>");
}

Can anyone tell me where I'm going wrong?

3
  • I would use a loop, an array, put the random number in the array key, and loop tell it has 3 items. Key duplicates will naturally be overwritten. Commented Dec 19, 2017 at 23:35
  • The thing is, you're checking if $B and $C are in_array only once, but nobody guarantees that 2nd time you won't get the same number again. Commented Dec 19, 2017 at 23:35
  • Checking if the number is in the array after putting it there doesn't make much sense. First move the if s before the in_array s. After that you need to worry about 'guessing' a duplicate twice or more. But one step at a time. Commented Dec 19, 2017 at 23:37

1 Answer 1

8

Like this ( as per my initial comment ),

$array = [];

while( count($array) < 3 ){
    $rand = mt_rand(1,36);
    $array[$rand] = $rand;
}

print_r( $array );

By setting the "key" to be the random number, we can abuse the fact that associative array keys are unique. Then it's a simple matter of waiting until the array contains the desired amount of unique items.

You can test it here

Outputs: ( your results may vary, it's random )

Array
(
    [16] => 16
    [20] => 20
    [27] => 27
)

UPDATE I was trying to think of a valid way to do it without using a loop ( on my way home from work ), and this way may be even better in some cases.

$a = range(1,36);

shuffle($a);

$array = array_slice($a, 0, 3);

print_r($array);

This will have better performance when the number of items you must find is higher. This is because there is no repetition, no collisions. So if you have a small range but need to find many items for the return, this will preform better. If you have many items and need to return only few, then the first one may be better, if not from speed then from memory use.

You can see it here

For reference this uses

range() - Create an array containing a range of elements.

http://php.net/manual/en/function.range.php

shuffle() - Shuffles (randomizes the order of the elements in) an array. It uses a pseudo random number generator that is not suitable for cryptographic purposes.

http://php.net/manual/en/function.shuffle.php

array_slice() - Returns the sequence of elements from the array as specified by the offset and length parameters.

http://php.net/manual/en/function.array-slice.php

So to explain this last one

  • First we create an array that contains each of our possible numbers as an element. So for example like this [1,2,3,4,5,6, ...].
  • Next we shuffle it which randomizes the order of the whole array. Shuffle modifies the array by "reference" so it doesn't return our array and therefor there is no assignment ( I think it returns Boolean, however I'm at a loss as to how it could fail and return false, pretty much it just returns true which we don't want to overwrite our array with ). So our example then becomes this [16,20,27,14,5,1, ...]
  • Last we cut out the number of items we need to return. Finally we end the example with this [16,20,27];

You can crunch the first one down into one ( really 2) line by assigning the value of the $rand variable in the condition of the loop. Like this:

$array = [];

while( count($array) < 3 && false !== ($rand = mt_rand(1,36))) $array[$rand] = $rand;

Because mt_rand(1,36) will never return boolan false. Also if I remember mt_rand is the same as rand now, or at least in current PHP versions.

Note: As of PHP 7.1.0, rand() uses the same random number generator as mt_rand(). To preserve backwards compatibility rand() allows max to be smaller than min as opposed to returning FALSE as mt_rand(). http://php.net/manual/en/function.rand.php

Hope it helps you, remember to think outside of the box.

Sign up to request clarification or add additional context in comments.

7 Comments

after I first thought it won't work, I realized that you use the random value as key - and so get the key result. nice solution!
Brilliant, if I don't say so myself! if you want to clear the "keys" do $array = array_values($array);
Holding my popcorn until somebody clears the keys inside the while loop. Hint: don't; do it later. Great answer!
Thanks bruh... I'm gonna use the first option. It's simpler to follow, and I'm a novice at this. But I still don't know how to assign the array results to the the three numbers. Assist?
What do you mean assign the array results to the the three numbers you'll get an array like in the example like this Array ( [16] => 16 [20] => 20 [27] => 27 )
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.