PHPで宝くじの乱数を6つ生成する

このプログラムは0から45までの6つの乱数を生成し、その数を繰り返すことはできません。このコードを改善できますか?

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

回答

アルゴリズムは機能していますが、ただし、必ずしも効率的であるとは限りません。数値の数が増えると、衝突が頻繁に発生します。

通常、一意の数値のセットから始めて、乱数を抽出する方が適切です。乱数を選択する代わりに、これらの数値を選択し、一意性をテストします。

PHPには、組み込みのシャッフル関数があるため、これは比較的適切です。 (つまり、基本的には、同じランダムシステムを使用してフィッシャー-イェーツシャッフルを実行します)。

つまり、一意の値の配列を取得し、シャッフルして選択し、結果を並べ替えます。

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

注:定数の代わりに名前付き変数を使用すると、

これがideoneで実行されていることを確認してください: https://ideone.com/1Hh0y8

コメント

  • 45から6つの異なる数値を生成する場合、衝突があっても、45要素の配列をシャッフルするよりも多くの乱数が必要になることはほとんどありません。そして、典型的な宝くじの場合、6と45が大幅に変わるとは思えません。
  • @ 200_success-同意しました。最初の文では効率について言及していますが、それはアルゴリズムについてですが、本当のポイントはきちんとしたことです。およびコードの機能。上記でも2レベルのネストが削除され、マジックナンバー宣言を除いて、'はわずか4行のコードになりました。

回答

変数$iは、count($numbers)が使用されたため、演算子を<=から<に変更する必要がありました。

whileforループとして書き直すことができます-例:

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

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です