Genereer 6 willekeurige getallen voor loterij in PHP

Dit programma genereert 6 willekeurige getallen tussen 0 en 45 en de getallen kunnen niet worden herhaald. Kan deze code worden verbeterd?

$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); 

Antwoord

Uw algoritme is functioneel, maar is niet per se erg efficiënt, en het zal vaker botsen, en vaker als het aantal getallen toeneemt.

Het is over het algemeen netter om te beginnen met een unieke reeks getallen en een willekeurige selectie van die getallen, in plaats van willekeurige getallen te selecteren en te testen op uniekheid.

PHP maakt dit relatief netjes, omdat het een ingebouwde shuffle-functie heeft (dat is in feite een Fisher-Yates shuffle uitvoeren met hetzelfde willekeurige systeem als jij).

Dus, verkrijg een array van de unieke waarden, schud het, maak er een selectie van en sorteer het resultaat:

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

Let op: benoemde variabelen gebruiken in plaats van constanten maakt het is duidelijker wat je aan het doen bent.

Bekijk dit op ideone: https://ideone.com/1Hh0y8

Opmerkingen

  • Het genereren van 6 verschillende getallen van de 45 heeft waarschijnlijk niet meer willekeurige getallen nodig dan het in willekeurige volgorde afspelen van een array van 45 elementen, zelfs niet bij botsingen. En ik betwijfel of 6 en 45 veel zullen veranderen voor een typische loterij.
  • @ 200_success – overeengekomen, en hoewel mijn eerste zin efficiëntie noemt, dat gaat over het algoritme, gaat het echte punt over netheid, en functie van de code. Met het bovenstaande worden ook twee nestniveaus verwijderd, en met uitzondering van de declaraties van het magische getal, ' is nu slechts 4 regels code.

Answer

De variabele $i kan worden verwijderd als count($numbers) werd in plaats daarvan gebruikt, waardoor de operator moest worden gewijzigd van <= naar <.

De while kan worden herschreven als een for lus – bijv.

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

Geef een reactie

Het e-mailadres wordt niet gepubliceerd. Vereiste velden zijn gemarkeerd met *