Pregunta

Usando PHP (otros lenguajes, usando incorporados comunes son bienvenidos), ¿cómo puedo obtener un número aleatorio (o pseudoaleatorio) que NO coincida con ciertos criterios?

IE: Quiero $ x = rand (0, 99) pero solo si ($ x% 9)! = 0 .

¿Cuál es una forma limpia y aceptable de restringir números aleatorios a un criterio como ese?

Como ejemplo, usando un bucle while () , y posiblemente break ing cuando tenemos algo que cumple con nuestros criterios, ¿y luego usando el número aleatorio después del bucle? :

while ( ($rand_key = array_rand($array_of_items)) && ($rand_key % 9 == 0) ) 
{ 
    // Do nothing?
}

O algo así como:

while ( $rand_key = array_rand($array_of_items) ) 
{ 
    if ( $rand_key % 9 == 0 ) {
        break;
    }
}

¿O hay una manera más concisa o apropiada de lograr esto?

¿Fue útil?

Solución

Uno de los raros casos en los que un bucle do-while realmente ayuda

$testData = array( 7, 8, 9 );

do {
  $rand = array_rand( $testData );
} while ( $testData[$rand] % 9 == 0 );

echo $testData[$rand];

Otros consejos

¿Es ese su caso de uso exacto, o solo un ejemplo?

Si está tratando (en particular) de obtener números del 0 al 99 excluyendo múltiplos exactos de 9, puedo pensar en un par de maneras de evitar los bucles incómodos. A la gente no le gusta hacer un ciclo mientras genera números aleatorios porque podrías hacerlo para siempre. (Pero, por supuesto, eso no sucederá a menos que seas del tipo extremadamente desafortunado, el tipo de persona que se mete en tiroteos con Clint Eastwood en spaghetti westerns).

  1. Podría tener una tabla de búsqueda que reasigna los números aleatorios que obtienes en los que quieras.

  2. Genera 0-88 al azar. Multiplica el resultado por 9 y dividirlo por 8 y obtener el resultado entero (piso, no redondo). Luego agregue 1.

Ambos tienen tiempos predecibles.

Un método alternativo, que intercambia espacio para, potencialmente, múltiples llamadas PRNG, para casos con un pequeño número de resultados válidos (como en su ejemplo) sería llenar una matriz con las soluciones válidas y usar el PRNG para producir un índice en la matriz.

Cualquiera que sea el método que elija, también sugeriría, para el código de producción, que tome nota de la razón de la restricción de manera apropiada y accesible.

Esto coincide con el requisito 'conciso':

while( ($x = rand(0, 99)) % 9 == 0 );
echo $x;

o

while ( $array_of_items[$rand_key = array_rand($array_of_items)] % 9 == 0 ); 
echo $array_of_items[$rand_key];     

Sin embargo, no es muy legible.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top