This program generates 6 random numbers between 0 and 45 and the numbers cannot be repeated. Can this code be improved?

$numbers = [];

$i = 1;

while($i <= 6)
    $number = mt_rand(0, 45);

    if(!in_array($number, $numbers))
        array_push($numbers, $number);


echo implode(" - ", $numbers);

2 Answers 2


Your algorithm is functional, but is not necessarily very efficient, and it will collide more, and more often if the count of numbers increases.

It's generally neater to start off with a unique set of numbers, and to extract a random selection of those numbers, instead of selecting random numbers, and testing for uniqueness.

PHP makes this relatively neat, because it has a built-in shuffle function (that's essentially doing a Fisher-Yates shuffle using the same random system that you are).

So, get an array of the unique values, shuffle it, take a selection of it, and sort the result:

$count = 6;
$highball = 45;
$numbers = range(0, $highball);
$drawn = array_slice($numbers, - $count);

Note, using named variables instead of constants makes it clearer what you are doing.

See this running on ideone: https://ideone.com/1Hh0y8

  • 1
    \$\begingroup\$ Generating 6 distinct numbers out of 45 is not likely to need more random numbers than shuffling a 45-element array, even with collisions. And I doubt that 6 and 45 will change by much, for a typical lottery. \$\endgroup\$ Mar 30, 2016 at 1:01
  • \$\begingroup\$ @200_success - agreed, and although my first sentence mentions efficiency, that is about the algorithm, the real point is about neatness, and function of the code. 2 levels of nesting are removed with the above too, and excluding the magic-number declarations, it's now just 4 lines of code. \$\endgroup\$
    – rolfl
    Mar 30, 2016 at 1:04

The variable $i could be eliminated if count($numbers) was used instead, which would require the operator to be changed from <= to <.

The while could be rewritten as a for loop - e.g.

for ($numbers = []; count($numbers)  < 6; /* intentionally empty */ )

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.