Lottery number analysis - php

I'm trying to perform some basic analysis on Lotto results :)
I have a database that looks something like:
id|no|day|dd|mmm|yyyy|n1|n2|n3|n4|n5|n6|bb|jackpot|wins|machine|set
--------------------------------------------------------------------
1 |22|mon|22|aug|1999|01|05|11|29|38|39|04|2003202| 1 | Topaz | 3
2 |23|tue|24|aug|1999|01|06|16|21|25|39|03|2003202| 2 | Pearl | 1
That's just an example. So, n1 to n6 are standard balls in the lottery and bb stands for the bonus ball.
I want to write a PHP/SQL code that will display just one random sequence of numbers that have yet to come out. However, If the numbers 01, 04, 05, 11, 29, 38 and 39 have come out, I don't want the code to print out them numbers but just in a different order, as in theory them set of numbers are already winning numbers.
I just can't get my head around the logic of this. I'd appreciate any help.
Thanks in advance

Assuming that the balls are stored in ascending order in your database like the examples you've given, you could just generate a random sequence of 6 numbers, sort them and then generate 1 random bonus number. Once you've done that it would just be a matter of doing a simple SQL query into your database and seeing if it comes back with a result:
$nums=...//generate your 6 numbers plus bonus number here
sort($nums);
$mysqli=new mysqli('...','...','...','...');
$stmt=$mysqli->prepare("SELECT * FROM table
WHERE n1=? AND n2=? AND n3=? AND n4=? AND n5=? AND n6=? AND bb=?");
$stmt->bind_param('iiiiiii', $nums[0], $nums[1], $nums[2], $nums[3], $nums[4], $nums[5], $nums[6]);
$stmt->execute();
$stmt->store_result();
if($stmt->num_rows==0)
//your numbers have not been drawn before - return them
else
//otherwise loop round and try again
As long as both list of numbers (but not the bonus ball) are sorted you won't have any problems with a different ordering of an already drawn set of numbers.
This will become less efficient as your database of previous draws gets fuller, but I don't think you'll have to worry about that for a few decades. :-)

What about sorting each already drawn result (each row) in some order, ascending maybe, then sort the set of already drawn results (all rows)? Then you will have a easy to look up in list in which you can see what is left to be drawn.
Say for example you want a never drawn set before? You would just have to loop through the list until you spot a "hole", which would be a never before drawn set. If you would like to optimise further you could store at what index you last found a "hole" as well. Then you would never need to loop through the same part of the list twice, and you could even abandon "completed" parts of the list to save disk space, or if you would like the new number you come up with to seam random you could start at a random offset in the list.
To do this effectively you should make an extra column to store the pre-sorted set. For example if you have (5, 3, 6, 4, 1, 2) that column could contain 010203040506. Add in enough zeros so that the numbers occur on a fixed offset basis.

Related

From 6 random numbers calculate random three-digit number?

I have 4 years PHP and C# experience, but Math is not my better side.
I thnik that i need in this project use some math algorithms.
When page load I need randomly create 7 numbers, 6 are numbers that I can use to calculate given three digit number:
rand 1-9
rand 1-9
rand 1-9
rand 1-9
rand 10-100 //5 steps
rand 10-100 //5 steps
and given number to calculate is 100-999,
I can use this operations: +, -, /, *, (, )
What is best algorithm for this?
I probably need to try all possible combinations with this 6 numbers to calculate given number or closest number of calculations.
example:
let say that given three digit number is
350, and I need to calculate this number from this numbers:
3,6,9,5 10, 100
so formula for this is:
(100*3)+(5*10) = 350
if is not possible to calculate exact number, than calculate closest.
You don't need to solve this problem completely, you can introduce me to solve this problem by paste some pseudo, or describing how to do that.
I have no actual experience that might help you with this, though since you're asking for some insight, I'll share my thoughts on how to do this.
As I typed my answer, I realised that this is in fact a knapsack problem, which means you can solve it to optimality using any algorithm that solves the knapsack problem. I recommend using dynamic programming to make your program run faster.
What you need to do is construct all numbers you can generate by combining two numbers with an operator, so that after this you have a list containing the numbers you started with, and the numbers you generated.
Then you solve the knapsack problem using the numbers as items with their value as their weight, and the number as the weight you can store at most.
The only thing that is slightly different is that you have an extra constraint that says that you may only use a number once. So you need to add into your implementation that if you add a combination of numbers, that you must remove the option of storing another combination that is constructed with the same number.
You could enumerate all the solutions by building "Abstract syntax trees", binary trees with the following informations :
the leaves are the 6 numbers
the nodes are the operations, for example a node '+' with the leaf '7' for left son and another node for right son that is 'x' with '140' for left son and '8' for right son would represent (7+(140*8)). Additionally, at each node you store the numbers that you already used (the leaves used in the tree), and the total.
Let's say you store all the constructed trees in the associative map TreeSets, but indexed by the number of leaves you use. For example, the tree (7+(140*8)) would not be stored directly in TreeSets but in TreeSets[3] (TreeSets[3] contains several trees, it is also a set).
You store the most close score in BestScore and one solution of the BestScore in BestSolution.
You start by constructing the 6 leaves (that makes you 6 different trees consisting of only one leaf). You save the closer number in Bestscore and the corresponding leaf in BestSolution.
Then at each step, you try to construct the trees with i leaves, i from 2 to 6, and store them in TreeSets[i].
You take j from 1 to i-1, you take each tree in TreeSets[j] and each tree in TreeSets[i-j], you check that those two trees don't use the same leaves (you don't have to check at the bottom of the tree since you have stored the leaves used in the node), if so you build the four nodes '+', 'x', '/', '-' with the tree from TreeSets[j] as left son and the tree from TreeSets[i-j] and store all four of them in TreeSets[i]. While building a node, you take the total from both tree and apply the operation, you store the total, and you check if it is closer than BestScore (if so you update BestScore and BestSolution with this new total and with the new node). If the total is exactly the value you were looking for, you can stop here.
If you didn't stopped the program by finding an exact solution, there is no such solution, and the closer one is in BestSolution at the end.
Note : You don't have to build a complete tree each time, just build the node with two pointers on other trees.
P.S. : You may avoid to enumerate all the solutions by using the dynamic programming approach, as Glubus said. In this case, it would consist, at each step (i) to remove some solutions that are considered sub-optimal. But with this problem I'm not sure that is possible (except maybe remove the nodes with a total of 0).

Generating unique fixed integer ids from array of ids

So here is the situation... I got array of objects, each marked with unique integer id, and for each and every combination of those objects, I need to create new ones, each with unique ids. Problem is that that list of objects is dynamic, used in stateless environment, so newly generated ids must be same for every run.
To make it clearer what I need here, consider that array of objects as array of their ids, for example: [10, 7, 23]. And basically, I need to get ids for all the possible combinations:
10, 7
10, 23
7, 23
10, 7, 23
What's important here is that generated ids must be same for each distinct combination (for example: 10 and 7 should always produce same id). Also, newly added objects should not affect previously generated ids. So for example, when some new object is later on added to that list, ids generated from previous combinations must remain the same as before new object was added.
Currently, I have a solution that pretty much comes down to generating new id as a result of the sum of combining ids, so resulting ids are:
17
33
30
40
Of course, this approach can produce duplicate ids, and that's the reason I'm asking for advice for some more sophisticated algorithm. I also tried introducing fixed offset of 1000 for newly generated ids and multiplying sum with number of objects in combination, so that for example resulting ids are 1034 (1000+(10+7)*2), 1066 (1000+(10+23)*2), etc., but I'm not sure that it would save me from duplicates. :)
Clear mention, I need this for the purpose of certain PHP project, but as this problem is not language-specific, I hope that there are some good mathematicians that can bring some good solution. :)
Useful information is fact that combining ids are in range from 10000-99999 and maximum number of items in combination does not exceed 10.
Please note that I do not need solution for how to make all the combinations from array elements, but only that "formula" for producing integer id.
Thanks in advance.
Not really sure what your aim is, but I'll have a go...
Have you tried using character keys? For example 10, 7, 3 becomes a sequence with an underscore. Each sequence will have a unique hash.
$arrayOfKeys = array(10, 7, 3);
$hash = implode('_', $arrayOfKeys);
print $hash;
# 10_7_3
Personally I'd go for this simple approach. If you're using a database and you're not producing, say, 100k records per day, it should be pretty fast using an indexed (primary key or unique) varchar field.
If you are to create numbers, here a tip: take the length of the largest number and that will be the prefix of your sequence, e.g.:
10, 5, 1 -> 2100501
105, 45, 201 -> 3105045201
The prefix will tell you what the length of the following sequences are. I can't think of any way you'd get doubles... Anyone? ;)
Hope it helps...
Step 1: Sort the values you get.
eg: if you get 10, 7 or 7, 10 it should result result in 7, 10 before going to the ID generator. If you know the range of your numbers i.e lets assume [0-100] use radix or count sort, will be fast.
Step 2 : Represent the numbers as strings, seperated by any chosen seperator.(':') maybe.
eg: for 7, 10 id will become "7:10".
Sorting is being done to avoid generating different ID's for 10, 7 and 7, 10.
BTW What do these numbers represent?
I don't think this is possible unless you allow labels of increasing length.
Assume you have a maximum of N distinct objects, corresponding to N distinct labels.
If you want to be able to represent all possible pairs, assuming order in a pair does not matter, you potentially need N.(N-1)/2 extra labels, whatever they are, and you need to reserve them all.
And for all triples, N.(N-1).(N-2)/6, for all quads N.(N-1).(N-2).(N-3)/24...
This grows exponentially and will very quickly exceed the capacity of integers.
Any other solution that tries to compress the space of labels, such as hashing, will result in collisions. You can resolve the collisions by maintaining collision table, but this will break the "generated ids must be same for every run" requirement.

How do I group sum of variables in php that are closest to a value, but also unique

Let's say I have an array (5,3,5,7,10)
the number desired is 12
So i want the first stack to be:
------------------------ first output --------
7+5 = 12 (the best combination with lower number of variables) - exclude 7 and 5, don't ever use it
------------ second output ------------
10 - because it's the second variable closest to 12. (then exclude 10, don't ever use it)
------------ third output ----------
5+3 = 8 - because it's the third closest to 12
I searched all the internet but i don't find a clue
THankyou
This problem is a harder version of the Subset Sum Problem
The successive sub-problems are essentially the approximation version on a smaller subset. Solving this problem for large arrays exactly will be brutally slow.

PHP: Compare two sets of numbers, no dupes

I'm creating a lottery contest for my site, and I need to know the easiest way to compare numbers, so that no two people can choose the same numbers. It's 7 sets of numbers, each number is a number between 1 and 30.
For example, if user 1 chooses: 1, 7, 9, 17, 22, 25, 29 how can I make sure that user 2 can't choose those same exact number?
I was thinking about throwing all 7 numbers into an array, sort it so the numbers are in order, then join them into one string. Then when another user chooses their 7 numbers, it does the same, then compares the two. Is there a better way of doing it?
What you describe sounds like the best way to me, IF you are dealing with all submissions in the same script - I would trim(implode(',',$array)) the sorted array, store the resulting string in an array and call in_array() to determine whether the value already exists.
HOWEVER I suspect that what you are actually doing is storing the selections in a database table and comparing later submissions against this table. In this case (I am taking a liberty and assuming MySQL here but I would say it is the most common engine used with PHP) you should create a table with 7 columns choice_1, choice_2 ... choice_7(along with whatever other columns you want) and create a unique index across all seven choice_* columns. This means that when you try and insert a duplicate row, the query will fail. This lets MySQL do all the work for you.
Try array_diff. There are some really good examples on php.net.

Tournament bracket

Not sure of the best way to go about this?
I want to create a tournament bracket of 2,4,8,16,32, etc teams.
The winner of the first two will play winner of the next 2 etc.
All the way until there is a winner.
Like this
Can anyone help me?
OK so more information.
Initially I want to come up with a way to create the tournament with the 2,4,8,16,etc.
Then when I have all the users in place, if they are 16 players, there are 8 fixtures.
At this point I will send the fixture to the database.
When all the players that won are through to the next round, i would want another sql query again for the 2 winners that meet.
Can you understand what i mean?
I did something like this a few years ago. This was quite a while ago and I'm not sure I'd do it the same way (it doesn't really scale to double-elimintation or the like) How you output it might be a different question. I resorted to tables as it was in 2002-2003. There are certainly better techniques today.
The amount of rounds in the tournament is log2(players) + 1, as long as players is one of the numbers you specified above. Using this information you can calculate how many rounds there are. The last round contains the final winner.
I stored the player information something like this (tweek this for best practices)
Tournament
Name
Size
Players
Tournament
Name
Position (0 to tournament.size - 1)
Rounds
Tournament
Round
Position (max halves for each round)
Winner (player position)
Note in all my queries below, I don't include the "Tournament = [tournament]" to identify the tournament. They all need it.
It's rather simple to query this with one query and to split it out as needed for the different rounds. You could do something like this to get the next opponent (assuming there is one). For round 1, you'd simply need to get the next/previous player based on if it was even or odd:
SELECT * FROM Players WHERE Position = PlayerPosition + 1
SELECT * FROM Players WHERE Position = PlayerPosition - 1
For the next round, if the user's last Round.Position was even, you'll need to make suer that the next position up has a winner:
SELECT Player FROM Rounds WHERE Position = [playerRoundPosition] - 1
If not, the next player isn't decided, or there's a gap (don't allow gaps!)
If the users last Round.Position was odd, you'll need make sure there's a user below them AND that there's a winner below them, otherwise they should automatically be promoted to the next round (as there is no one to play)
SELECT COUNT(*) FROM Players WHERE Position > [Player.Position]
SELECT Player FROM Rounds WHERE Position = [playerRoundPosition] + 1
On a final note, I'm pretty sure you could use something like the following to reduce the queries you write by using something like:
SELECT Player FROM Rounds WHERE Position + Position % 2 = [playerRoundPosition]
SELECT Player FROM Rounds WHERE Position - Position % 2 = [playerRoundPosition]
Update:
Looking over my original post, I find that the Rounds table was a little ambigous. In reality, it should be named matches. A match is a competition between two players with a winner. The final table should look more like this (only the name changed):
Matches
Tournament
Round
Position (max halves for each round)
Winner (player position)
Hopefully that makes it a bit more clear. When the two players go up against each other (in a match), you store that information in this Matches table. This particular implementation depends on the position of the Match to know which players participated.
I started numbering the rounds at 1 because that was more clear in my implementation. You may choose 0 (or even do something completely different like go backwords), if you choose.
In the first round, match 1 means players 1 and 2 participated. In match 2, the players 3-4 participated. Essentially the first round is simply players position and position + 1 participated. You could also store this information in the rounds table if you need more access to it. Every time I used this data in the program, I needed all the round and player information anyways.
After the first round, you look at the last round of matches. In round 2, match 1, the winners from matches 1 and 2 participate. Round 2, match 2, the winners from match 3 and 4 participate. It should look pretty familiar, except that it uses the match table after round 1. I'm sure there's a more efficent way to do this repetitive task, I just never got enough time to refactor that code (it was refactored, just not that much).
Use arrays and remove the losing teams from the main array. (But keep 'em on a separate array, for reference and reuse purposes).

Categories