How to improve the process of generating non-repeated random numbers?

4

I have a algorithm for creating random numbers for lottery that have the following characteristics:

1 ° You must be informed of the number of numbers to be generated.

2 ° Numbers can not be repeated.

3 ° The numbers need to be in ascending order.

As a beginner in PHP, I tried to make the algorithm work. To do this, I created a class with a geraNumeros() function recursively in order to do all these items and return an array where I sort using asort() and then transform into string with implode() . Is there any way to optimize it?

<?php

class loterias{

   public function geraNumero($aQuantidade, $aMinimo, $aMaximo) {

      $contador = 0;
      $result = array();
      while ($aQuantidade):
         $result[$aQuantidade] = str_pad(rand($aMinimo, $aMaximo), 2, '0', STR_PAD_LEFT);
         $aQuantidade--;
         $contador++;
      endwhile;
      while ($contador !== count(array_unique($result))):
         $result = $this->geraNumero($contador, $aMinimo, $aMaximo);
      endwhile;
      return $result;
   }

}

// Parametros //
$quantidade = 6;
$minimo = 1;
$maximo = 60;

$mega = new loterias();
$result = $mega->geraNumero($quantidade, $minimo, $maximo);
asort($result);
var_dump($result);
    
asked by anonymous 08.01.2015 / 19:25

2 answers

6

With some functions for arrays I got the same result, here's an explanation of what each function does:

range() - Creates an array from a minimum to a maximum.

array_rand() - Randomly returns a key from an array. With the second parameter you can specify the number of elements you want to return.

array_flip() - Invert the value with the key of an array. I did this because in PHP the keys start with zero, and I think lotteries do not start with zero.

array_map() - For each element of an array, it performs a certain function, in the if it would be str_pad with the required parameters.

<?php

function geraNumeros($quantidade, $minimo, $maximo)
{
    $listaDeNumeros = range($minimo, $maximo);
    $numeros = array_rand(array_flip($listaDeNumeros), $quantidade);

    $numeros = array_map(function($value){
        return str_pad($value, 2, '0', STR_PAD_LEFT);   
    }, $numeros);

    return implode($numeros, ',');
}

echo geraNumeros(6, 1, 60) . PHP_EOL;
echo geraNumeros(6, 1, 60) . PHP_EOL;
echo geraNumeros(6, 1, 60) . PHP_EOL;
echo geraNumeros(6, 1, 60) . PHP_EOL;

Example on Ideone.

    
08.01.2015 / 20:20
4

I leave a solution that, in my opinion, has a simple code:

<?php

class loterias{

   public function geraNumero($aQuantidade, $aMinimo, $aMaximo) {
       if( $aQuantidade > ($aMaximo - $aMinimo) ) {
           return false;
       }

       $numeros = range($aMinimo, $aMaximo);
       shuffle($numeros);
       array_splice($numeros, 0, $aQuantidade);
       sort($numeros);
       return $numeros;
   }

}

Requirements can not be satisfied if the difference between the maximum and minimum are less than the quantity, so I did this validation (could have thrown an exception).

  • An array is created with all possible numbers.
  • Then they are shuffled with the "shuffle" function.
  • The first ones are chosen in the specified amount.
  • Are ordered.
10.01.2015 / 20:45