Generera 6 slumptal för lotteri i PHP

Detta program genererar 6 slumptal mellan 0 och 45 och siffrorna kan inte upprepas. Kan den här koden förbättras?

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

Svar

Din algoritm är funktionell, men är inte nödvändigtvis särskilt effektiv, och det kommer att kollidera mer och oftare om antalet siffror ökar.

Det är i allmänhet snyggare att börja med en unik uppsättning siffror och extrahera ett slumpmässigt val av dessa siffror istället för att välja slumpmässiga nummer och testa för unikhet.

PHP gör detta relativt snyggt eftersom det har en inbyggd shuffle-funktion (att ”i huvudsak gör en Fisher-Yates-blandning med samma slumpmässiga system som du är).

Så, få en matris med de unika värdena, blanda det, ta ett urval av det och sortera resultatet:

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

Obs! Använd namngivna variabler istället för konstanter gör det är tydligare vad du gör.

Se detta på ideone: https://ideone.com/1Hh0y8

Kommentarer

  • Att generera 6 distinkta nummer av 45 behöver sannolikt inte fler slumpmässiga nummer än att blanda en 45-elements array, även vid kollisioner. Och jag tvivlar på att 6 och 45 kommer att förändras mycket, för ett typiskt lotteri.
  • @ 200_success – överens om, och även om min första mening nämner effektivitet, det handlar om algoritmen, den verkliga poängen handlar om snygghet, och kodens funktion. Två nivåer av häckande tas bort med ovanstående, och exklusive de magiska nummerdeklarationerna är det ' nu bara fyra rader kod.

Svar

Variabeln $i kan elimineras om count($numbers) användes istället, vilket skulle kräva att operatören ändrades från <= till <.

while kan skrivas om som en for -slinga – t.ex.

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

Lämna ett svar

Din e-postadress kommer inte publiceras. Obligatoriska fält är märkta *