Este programa genera 6 números aleatorios entre 0 y 45 y los números no se pueden repetir. ¿Se puede mejorar este código?
$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);
Respuesta
Su algoritmo es funcional, pero no es necesariamente muy eficiente, y colisionará más, y más a menudo si aumenta el recuento de números.
En general, es mejor comenzar con un conjunto único de números y extraer un selección de esos números, en lugar de seleccionar números aleatorios y probar la singularidad.
PHP hace que esto sea relativamente ordenado, porque tiene una función de reproducción aleatoria incorporada (eso es esencialmente hacer una reproducción aleatoria de Fisher-Yates usando el mismo sistema aleatorio que tú).
Entonces, obtener una matriz de valores únicos, mezclarla, seleccionar una selección y ordenar el resultado:
$count = 6; $highball = 45; $numbers = range(0, $highball); shuffle($numbers); $drawn = array_slice($numbers, - $count); sort($drawn);
Nota, el uso de variables con nombre en lugar de constantes hace es más claro lo que está haciendo.
Vea esto ejecutándose en ideone: https://ideone.com/1Hh0y8
Comentarios
- No es probable que la generación de 6 números distintos de 45 necesite más números aleatorios que mezclar una matriz de 45 elementos, incluso con colisiones. Y dudo que 6 y 45 cambien mucho, para una lotería típica.
- @ 200_success – de acuerdo, y aunque mi primera oración menciona la eficiencia, se trata del algoritmo, el punto real es la pulcritud, y función del código. También se eliminan 2 niveles de anidación con lo anterior, y excluyendo las declaraciones de números mágicos, ' ahora solo tienen 4 líneas de código.
Respuesta
La variable $i
podría eliminarse si count($numbers)
en su lugar, lo que requeriría cambiar el operador de <=
a <
.
El while
podría reescribirse como un for
bucle, p. ej.
for ($numbers = []; count($numbers) < 6; /* intentionally empty */ )