Este programa gera 6 números aleatórios entre 0 e 45 e os números não podem ser repetidos. Este código pode ser melhorado?
$numbers = []; $i = 1; while($i <= 6) { $number = mt_rand(0, 45); if(!in_array($number, $numbers)) { array_push($numbers, $number); $i++; } } sort($numbers); echo implode(" - ", $numbers);
Resposta
Seu algoritmo é funcional, mas não é necessariamente muito eficiente e colidirá mais e com mais frequência se a contagem de números aumentar.
Geralmente, é mais organizado começar com um conjunto único de números e extrair um aleatório seleção desses números, em vez de selecionar números aleatórios, e testar a exclusividade.
O PHP torna isso relativamente simples, porque tem uma função de embaralhamento embutida (que basicamente está fazendo um Fisher-Yates embaralhar usando o mesmo sistema aleatório que você está).
Então, obtenha um array de valores únicos, embaralhe-o, selecione-o e classifique o resultado:
$count = 6; $highball = 45; $numbers = range(0, $highball); shuffle($numbers); $drawn = array_slice($numbers, - $count); sort($drawn);
Nota, usar variáveis nomeadas em vez de constantes torna fica mais claro o que você está fazendo.
Veja isto em execução no ideone: https://ideone.com/1Hh0y8
Comentários
- Gerar 6 números distintos entre 45 provavelmente não precisará de mais números aleatórios do que embaralhar uma matriz de 45 elementos, mesmo com colisões. E eu duvido que 6 e 45 mudem muito, para uma loteria típica.
- @ 200_success – concordo, e embora minha primeira frase mencione eficiência, isso é sobre o algoritmo, o ponto real é sobre organização, e função do código. 2 níveis de aninhamento também foram removidos com o acima e, excluindo as declarações de números mágicos, ' agora tem apenas 4 linhas de código.
Resposta
A variável $i
poderia ser eliminada se count($numbers)
foi usado em vez disso, o que exigiria que o operador fosse alterado de <=
para <
.
O while
pode ser reescrito como um for
loop – por exemplo,
for ($numbers = []; count($numbers) < 6; /* intentionally empty */ )