Avoiding array duplication

hello

i’ve set myself what i believe should be a fairly simple task but my limited knowledge of php and my total ignorance of the correct use of arrays has left me quite stumped.

i’m trying to make a simple little script that will emulate the UK national lottery draw - 49 uniquely numbered balls are spun around in a cylinder then 7 of them are randomly removed from the cylinder - these 7 balls make up the draw result. my aim is simply to replicate that system using php and eventually store the results in a database. the code posted below does what i expect it to do - it doesn’t however stop duplicate values from being entered into the array.

i need to check that each new random number hasn’t already been used previously - it seems logical to peform that check at each step rather than trying to fix the array once it’s been filled. my lack of experience & limited knowledge has me struggling to even begin approaching the problem though.

i’d really appreciate if anyone can offer up some hints/tips as to the simplest method of approach. thanks in advance.


<?php
// this script is designed to replicate the UK national lottery draw.
// 7 balls numbered 1-49 are selected randomly - each number MUST BE UNIQUE.
// i want to draw all 7 numbers in one instance, and store each result
// in a database to enable calculations to be performed later


$ballsdrawn = 0;
WHILE ($ballsdrawn<>7)
	{	
		$draw['ball1']= rand(1,49);
		$draw['ball2']= rand(1,49);
		$draw['ball3']= rand(1,49);
		$draw['ball4']= rand(1,49);
		$draw['ball5']= rand(1,49);
		$draw['ball6']= rand(1,49);
		$draw['bonusball']= rand(1,49);
		$ballsdrawn=7;
	}
	
echo "The first ball selected is number " . $draw['ball1'] . "<br/>";
echo "The second ball selected is number " . $draw['ball2'] . "<br/>";
echo "The third ball selected is number " . $draw['ball3'] . "<br/>" ;
echo "The fourth ball selected is number " . $draw['ball4'] . "<br/>";
echo "The fifth ball selected is number " . $draw['ball5'] . "<br/>";
echo "The sixth ball selected is number " . $draw['ball6'] . "<br/>";
echo "The bonus ball is number " . $draw['bonusball'];
?>

<form action="lotto.php" method="post">
  <button type="submit">PLAY AGAIN</button>
</form>

This?


<?php

$balls  = range( 1, 49 );
$result = array();

for ( $i = 0; $i < 7; $i++ ) {
  shuffle( $balls );
  $result[] = array_shift( $balls );
}
  
echo "The winning number is: " . join( $result, ' - ' );

thank you for your quick response.

while the code you posted does exactly what i wanted, i’m pretty mystified by how it’s actually getting the desired result.

i didn’t even know the commands “range” and “shuffle” existed - it’s not something i’d ever come across up until now. which part of the code is preventing the same number appearing more than once? does the “shuffle” command ‘remove’ the selected number from the range(1-49) or am i totally misunderstanding what’s going on there?

i think i need to get myself a good php reference book, and practice a lot more. thanks again for your help though - much appreciated!

The code is beautiful in it’s simplicity!

Basically it starts by creating an array of all numbers from 1 to 49.

Then it loops 7 times, one for each ball.

Each loop, it ‘shuffles’ the array around - in other words, it sorts them into a random order. It then grabs the first value (which can be anything from 1 to 49, because the array is in a random order) and removes it - all of this is done by array_shift.

So in the second iteration of the loop, the array has 48 items - it no longer has the value grabbed by the first iteration, so it can’t possibly get the same value.

Jake forgot to link the function reference, http://us.php.net/manual/en/function.array-shift.php :slight_smile:

I see no reason to include shuffle() in the loop, as it seems unnecessarily inefficient. Perhaps I’ve misunderstood the algorithm, but the OP never indicated the balls were reshuffled after each pick.

<?php

$draw = 7;
$balls = range(1, 49);
shuffle($balls);

/* first $draw balls, no duplicates */
$picks = array_slice($balls, 0, $draw);

echo 'Picks: ', rtrim(join(', ', $picks), ', ');

I’m not sure there was or is an algorithm. My original thinking if emulating a lottery event the balls would be shuffled after each. That was my thinking when I spent 5 seconds writing it. :stuck_out_tongue:

Wrong word on my part, I think. I meant to refer to the OP’s description of the problem, so maybe “the spec” (from which algorithms are derived) is more appropriate.

My original thinking if emulating a lottery event the balls would be shuffled after each. That was my thinking when I spent 5 seconds writing it. :stuck_out_tongue:

Ah okay, I see your point.

thanks jake for the explanation of the code - i understand now what is actually happening and why - and i do have to agree it is quite a lovely little chunk of code so thanks again logic for sharing your knowledge.

i understand why dyer85 suggested that it’s perhaps not the most efficient method, but the actual lottery keeps shuffling all the balls until all the numbers have been drawn so it’s a quite realistic replication of that system.

i’ve added some code to insert all the generated numbers into a database so now i can start performing various calculations, view statistics, etc. i should probably point out that i’m not actually attempting to win the lottery with this code! my hobby/project that i’m working towards will involve a lot of random number generation and manipulation so this little task seemed like a good way to begin learning.

thanks again to everyone.