|
|
Subject:
enumerating lotto combinations
Category: Science > Math Asked by: xman-ga List Price: $10.00 |
Posted:
09 Jun 2004 05:46 PDT
Expires: 13 Jun 2004 23:43 PDT Question ID: 358561 |
"Tattslotto" has 6 balls drawn from a group of 45. There is about a 1 in 8 million chance of a random that set of 6 numbers matches the 6 balls drawn. stated another way, there are about 8 million posible combinations of the 6 drawn balls. I want a one-to-one mapping of integers 1 to approx. 8 million to each possible 6 ball combination. HOWEVER, I don't want a "look up" table. I want a neat formula or algorithm (that does not simply cycle through combinations, thus recreating part of a "look up" table). So for example, if I input the number 6,543,210 the formula will output a unique 6 ball combination such as {17, 18, 31, 35, 36, 44}. |
|
There is no answer at this time. |
|
Subject:
Re: enumerating lotto combinations
From: touf-ga on 09 Jun 2004 16:38 PDT |
There are two problems which come forth in deriving a magic formula to give you what you are looking for. 1) you are trying to look at ONLY 8 million (8,145,060 to be exact) of the potential 5,864,443,200 combinations of lotto number arrangements. Now, I know what you are thinking...5.8 billion? This guy must be off his rocker. Well, think about it - for the first number, you have 45 potential balls. For the second ball, you have 44, and so on til you get to the sixth ball, which leaves you with 40 combinations. Of course, this assumes there are no repeats and that there is no "powerball" or anything of that nature. The reason you really have 8.1 million, though, is that lotto does not have any preference for the order of numbers drawn. That is to say, 1,2,3,4,5,6 and 2,4,3,1,5,6 and 6,1,5,2,4,3 are all the same. In fact, for each set of six numbers, you have (6!) combinations of those numbers, or 720 combinations. 8.1 million x 720 = 5.8 billion. Problem 1 is that if you have a magic formula, which of the 720 number orders does it go with? Magic formulas don't like that. Problem 2 is that you don't want a "lookup table", and you don't want a program which recreates a lookup table. This ties in with problem 1, because, well, it basically limits your choices down to zero. If I were doing this, I would create a number of two-dimensional arrays. One very large array would work just as well, although it may crash your computer. Let's see how to do it with one large array, and you can adjust as required. We start with one array 6 x 8145060. (wow!) So, ideally, once you're done ,you type in a column number, from 1 to 8.1 million, and you get all six rows of that column, each row signifying one of the six lotto numbers. next, you start up a "for loop", from 1:8145060 in increments of +1. within that for loop, you have another one, incrementing from 1:6. within that one, 1:45 within that one, 2:44 within that one, 3:43 within that one, 4:42 within that one, 5:41 within that one, 6:40 and you just record whatever number your loop is on at that moment into your jumbo array. so, k(first loop count,2nd loop count) = eight loop count. and you keep doing this for your entire array. To make sure you don't get repeats, you have to simply always look for combinations whose numbers are GREATER (not >=) than the number preceding it. For instance, you'd look for 1,2,3,4,5,6. Once you get to 2, you have to make sure not to do 2,1..., not 2,2...., but rather, 2,3..... So pretty soon, you have a jumbo array. You type in your column number, and you get one of 8.1 million combinations. Enjoy. That is to say, |
Subject:
Re: enumerating lotto combinations
From: touf-ga on 09 Jun 2004 16:40 PDT |
That is to say, good luck. |
Subject:
Re: enumerating lotto combinations
From: crythias-ga on 09 Jun 2004 17:17 PDT |
The following should work for you... the printf (".") is used to indicate increments of the first "ball", and you can remove it safely. This is very much a "brute force" method, which means high numbers are necessarily going to take time, which is why I added the "." to indicate that something *is* going on. get awk95.exe from anywhere and put it in your path: awk95 -f enum.awk 6543210 -=-=-=- begin enum.awk -=-=-=-=- BEGIN { lookup=ARGV[1] print (ARGV[1]) b[1]=1 b[2]=2 b[3]=3 b[4]=4 b[5]=5 b[6]=5 for (i=1;i<=lookup;i++) { b[6]++ if (b[6]>45) { b[5]++ if (b[5]>44) { b[4]++ if (b[4]>43) { b[3]++ if (b[3]>42) { b[2]++ if (b[2]>41) { b[1]++ printf(".") if (b[1]>40) { b[1]=40 } b[2]=b[1]+1 } b[3]=b[2]+1 } b[4]=b[3]+1 } b[5]=b[4]+1 } b[6]=b[5]+1 } } printf( "%d,%d,%d,%d,%d,%d\n", b[1],b[2],b[3],b[4],b[5],b[6] ) } -=-=-=-=-End enum.awk-=-=-=-=- |
Subject:
Re: enumerating lotto combinations
From: xman-ga on 09 Jun 2004 19:55 PDT |
Thanks for your help touf and crythias. I acknowledge that the "look up" table method is a simple solution to enumerating lotto combinations (especially given the power of computers these days). But I have an intuition that there might be a simpler mapping function. Like both of you have pointed out, I have realised that putting the combinations into a ascending ordering simplifies the problem somewhat. I have been toying with ideas of tree diagrams and curves to represent the ascending nature of the combinations. for example, drawing a table with 6 columns and 45 rows, each column filled with numbers 1 to 45. all possible combinations can be represent by the family of curves that passes through one cell in each column and is increasing. anyway, thanks again. |
Subject:
Re: enumerating lotto combinations
From: crythias-ga on 09 Jun 2004 21:31 PDT |
What you don't realize is that you cannot have each ball represent 45 numbers. I had to program this thing above to actually make this work correctly, and it does work... The minimum combination of numbers *must* be: 1,2,3,4,5,6 And ball 6 is always >ball 5, <=45 ball 5 is always >ball4, <=44 ball 4 is always >ball3, <=43 ball 3 is always >ball2, <=42 ball 2 is always >ball1, <=41 ball 1 is always >=1, <=40 The maximum is: 40,41,42,43,44,45 You're welcome to try whatever you want to try, but I'm willing to say this is every combination, without repeats, one to one, Once you've created lotolist.csv, you have a lot of luxuries. You can use a batch file to call a number, VERY fast: -=-=-=- begin getloto.bat -=-=-=- awk95 "{if (NR==%1) print $0}" lotolist.csv -=-=-=- end getloto.bat -=-=-=-=- call it with: getloto 654321 This is new and creates what you didn't ask for: a lookup table. awk95 -f enumall.awk > lotolist.csv -=-=-=- begin enumall.awk -=-=-=-=- BEGIN { b[1]=1 b[2]=2 b[3]=3 b[4]=4 b[5]=5 b[6]=5 lookup=8145060 for (i=1;i<=lookup;i++) { b[6]++ if (b[6]>45) { b[5]++ if (b[5]>44) { b[4]++ if (b[4]>43) { b[3]++ if (b[3]>42) { b[2]++ if (b[2]>41) { b[1]++ if (b[1]>40) { b[1]=40 } b[2]=b[1]+1 } b[3]=b[2]+1 } b[4]=b[3]+1 } b[5]=b[4]+1 } b[6]=b[5]+1 } printf( "%d,%d,%d,%d,%d,%d\n", b[1],b[2],b[3],b[4],b[5],b[6] ) } } -=-=-=- End enumall.awk -=-=-=-=- |
Subject:
Perhaps what you're looking for
From: kaif-ga on 09 Jun 2004 22:25 PDT |
The following code snippet in C does precisely what you want. Let me know if you'd like any help deciphering or translating any of it. ===== lotto.c ===== #include <stdio.h> int main( ) { int i, j; // Only precomputation table int ncr[46][6] = {{ 1, 0, 0, 0, 0, 0 }}; for( i = 1; i <= 45; i++ ) { ncr[i][0] = 1; for( j = 1; j <= 5; j++ ) ncr[i][j] = ncr[i-1][j] + ncr[i-1][j-1]; } // Input int x; printf( "Input number: " ); scanf ( "%d", &x ); if( x <= 0 || x > 8145060 ) { fprintf( stderr, "Number %d out of range 1 .. 8,145,060.\n", x ); return 5; } // Processing/output int more = 6; for( i = 1; more > 0; i++ ) { if( x <= ncr[45-i][more-1] ) { printf( "%d\n", i ); more--; } else { x -= ncr[45-i][more-1]; } } return 0; } =================== The algorithm requires a precomputed table of size 46*6 = 276 entries, where ncr[i][j] is the number of ways of choosing j objects given i objects. We need this table for 0 <= i <= 45 and 0 <= j < 6. The program actually computes a mapping that sends 1 -> 1, 2, 3, 4, 5, 6 2 -> 1, 2, 3, 4, 5, 7 .. 40 -> 1, 2, 3, 4, 5, 45 41 -> 1, 2, 3, 4, 6, 7 .. 8145060 -> 40, 41, 42, 43, 44, 45 that is to say, it always outputs the numbers in increasing order, and it does so in a very logical fashion (namely, in "lexicographical" order). It does this by repeatedly asking itself, for a number i from 1 to 45, "should I add i to my sequence?" It can answer this because ncr[45-i][# of numbers still to choose minus 1] indicates how many sequences there are that begin with what we already have chosen AND have "i" as the next element of the sequence. Hope this helps! - kaif-ga. |
Subject:
Re: enumerating lotto combinations
From: xman-ga on 09 Jun 2004 23:20 PDT |
thanks Kaif, for another elegant solution. I fear that the question I have asked may be impossible to answer with the parameters that I set (ie. solving without a "look up" table). So please accept my apologies. I really appreciate the effort that you have put into this question, and welcome any further comments. |
Subject:
Re: enumerating lotto combinations
From: xman-ga on 10 Jun 2004 05:30 PDT |
Hello Kaif, I just had another look at the code and comments you supplied... it is indeed exactly what I wanted (although I haven't tested it yet)... I consider this a full answer to my question, so if you submit it as an answer you can collect the $10. Thanks again. |
Subject:
Re: enumerating lotto combinations
From: crythias-ga on 10 Jun 2004 06:59 PDT |
Reminder: if there isn't a link under a name, we aren't Google Answer Researchers, so we can't get paid. I'm interested to know why kaif's method is accepted and mine isn't? Different formula doing the exact same thing... If you want to make a formula that relies on "randomness", and you have a RANDOMIZE type function available (that is, you can self-populate the random number generator seed of your code base), here's a quick BASIC type code: RANDOMIZE (Seed) b1=int(rnd()*40)+1 b2=int(rnd()*(40-b1))+ b1+1 b3=int(rnd()*(41-b2))+ b2+1 b4=int(rnd()*(42-b3))+ b3+1 b5=int(rnd()*(43-b4))+ b4+1 b6=int(rnd()*(44-b5))+ b5+1 I cannot guarantee no duplicates in the list, that is, I cannot guarantee a random seed of 12345 doesn't generate the same list as a random seed of 54321, but it is highly likely that you will have a good representation, unique numbers, and repeatable results with the same seed number. |
Subject:
Re: enumerating lotto combinations
From: mathtalk-ga on 10 Jun 2004 07:22 PDT |
I suspect that the lookup table can be "eliminated" by using recursive function calls. Of course the principle remains the same: those combinations of 6 things drawn from 45 whose lowest ball is N correspond precisely to combinations of 5 things drawn from 45-N. Pre-computing the combinations vs. calculating them on the fly could save a little time, but if we'd need to "precompute" them for each run, calculating them on the fly should be slightly more efficient (since we'd only compute half of them "on average"). --mathtalk-ga |
Subject:
Re: enumerating lotto combinations
From: crythias-ga on 10 Jun 2004 13:25 PDT |
I just wanted to give props to kaif for the solution posted. I'm not sure how a scalar (x) maps to a vector/array (I don't know how (x <= ncr[45-i][more-1]) actually can be compared, but I'm impressed at the 276 that was posited. My mind was reeling, though, at the thought that, if there is the ability to have a set of 276 entries, then any given number should be a multiple and/or offset of a base entry. I don't have an idea how to make this theory into a formula, but my gut feeling is that the lookup value could directly manipulate the 276 entries. |
Subject:
Re: enumerating lotto combinations
From: kaif-ga on 10 Jun 2004 14:52 PDT |
I've realized that I really don't need the ncr[45] row of my table, but that's largely irrelevant. A few comments: To xman-ga: I am indeed not a Google Researcher and cannot accept the $10. Thanks for the question however. To crythias-ga: The array ncr[][] is two-dimensional, so ncr[45-i][more-1] is simply an integer. To mathtalk-ga: I'd fear the recursive calls, personally, because that would likely take an exponential amount of time if you're not careful; if you are, then it should be simply equivalent to recomputing most of my table anyway. Something that could perhaps replace the ncr[][] lookup is a call to the following: int ncr( int n, int r ) { int result = 1; for( i = 1; i <= r; i++ ) { result *= (n-i+1); result /= i; } return result; } I believe that should work, but I have not tested it. During any run of my program, there would be at most 45 calls to this subroutine, and each one performs at most 10 numerical operations. |
If you feel that you have found inappropriate content, please let us know by emailing us at answers-support@google.com with the question ID listed above. Thank you. |
Search Google Answers for |
Google Home - Answers FAQ - Terms of Service - Privacy Policy |