Computer Science Canada Question Regarding a Card Combinations Program |
Author: | _Dan_ [ Sat Jan 12, 2008 2:36 pm ] |
Post subject: | Question Regarding a Card Combinations Program |
Hello, I am a student studying first-year Java in high-school, and I was just wondering what would be the easiest solution to the following problem: Definition of a Card: Values {2-11} Suits {5 Suits} 50 Cards in Total I need to figure out (for a program for another class I am making) how to go through all possible 4 card VALUE combinations (suit is irrelevant) (order matters, hence if the values in a hand are 1,2,3,5 then the hand 5,3,1,2 would be identical, and should not be counted if 1,2,3,5 has already been counted). The program I have right now (which is obviously incorrect) is: Quote: int[] values = new int [50];
//I know I can make the following code more efficient, but //efficiency is not important for this program, I just need help on the next part for (int value = 2 ; value < 12 ; value++) { values [value - 2] = value; } for (int value = 2 ; value < 12 ; value++) { values [value + 8] = value; } for (int value = 2 ; value < 12 ; value++) { values [value + 18] = value; } for (int value = 2 ; value < 12 ; value++) { values [value + 28] = value; } for (int value = 2 ; value < 12 ; value++) { values [value + 38] = value; } //Go through all possible value combinations for (int first = 0 ; first < 50 ; first++) { for (int second = second + 1 ; second < 50 ; second++) { for (int third = second + 1 ; third < 50 ; third++) { for (int fourth = third + 1 ; fourth < 50 ; fourth++) { System.out.print (values [fourth]); System.out.print (" "); System.out.print (values [second]); System.out.print (" "); System.out.print (values [third]); System.out.print (" "); System.out.println (values [fourth]); } } } } The problem is some hands are found multiple times . Anxiously Waiting for Help, Dan |
Author: | Tony [ Sat Jan 12, 2008 5:10 pm ] | ||||
Post subject: | RE:Question Regarding a Card Combinations Program | ||||
I think you might have some typos in there...
There are different ways of preventing the same combinations from appearing. The least efficient, but probably the simplest to understand, method is to sort each hand and check if such order has previously appeared. |
Author: | OneOffDriveByPoster [ Sat Jan 12, 2008 9:16 pm ] |
Post subject: | Re: Question Regarding a Card Combinations Program |
You could simply ignore the first part of your code and the idea of 50 cards entirely. Make your for loops generate each value combination that is in sorted order. So value(card1) <= value(card2) <= value(card3) <= value(card4). We know that for each value we have enough cards for this to work. |
Author: | _Dan_ [ Sat Jan 12, 2008 11:34 pm ] |
Post subject: | Re: Question Regarding a Card Combinations Program |
Quote: method is to sort each hand and check if such order has previously appeared.
That's wayyy too inefficient, isn't it? I think the program would run for like a day :S, there are >300 million for loop runs, and each would have to check all of the hands before it. Quote: So value(card1) <= value(card2) <= value(card3) <= value(card4). We know that for each value we have enough cards for this to work.
I thought of that before, however the problem is that there are more than 4 suits, hence only four of the 5 2's would be placed in the first few hands (it should be 2,2,2,2 then 2,2,2,2 then 2,2,2,2 then 2,2,2,2 then 2,2,2,2 but the last hand will not appear using this method if I understood you correctly). |
Author: | OneOffDriveByPoster [ Sun Jan 13, 2008 12:06 am ] |
Post subject: | Re: Question Regarding a Card Combinations Program |
Quote: I thought of that before, however the problem is that there are more than 4 suits, hence only four of the 5 2's would be placed in the first few hands (it should be 2,2,2,2 then 2,2,2,2 then 2,2,2,2 then 2,2,2,2 then 2,2,2,2 but the last hand will not appear using this method if I understood you correctly). I thought you said suit does not matter. 2,2,2,2 should be listed only once, no? |
Author: | Tony [ Sun Jan 13, 2008 12:07 am ] |
Post subject: | Re: Question Regarding a Card Combinations Program |
_Dan_ @ Sat Jan 12, 2008 11:34 pm wrote: That's wayyy too inefficient, isn't it?
"sorting" can be implemented via O(1) encoding binary tree lookup is O(log n) alternatively you could find everything, with repeats. Then sort that list O(nlogn) and remove any repeating elements O(n) |
Author: | _Dan_ [ Sun Jan 13, 2008 12:12 am ] |
Post subject: | Re: Question Regarding a Card Combinations Program |
Wait, firstly I have to figure out how to even GET at least every hand in the array, and my current way does not do this, and secondly, how do I know whether or not to remove a hand from the array of hands (for example there are 5 (2,2,2,2) hands, and 100(2,2,3,3) hands)? Quote: I thought you said suit does not matter. 2,2,2,2 should be listed only once, no?
I meant that I did not need to store the suits of the cards, however there are still 5 different "types" of each card. |
Author: | OneOffDriveByPoster [ Sun Jan 13, 2008 1:33 am ] |
Post subject: | Re: Question Regarding a Card Combinations Program |
_Dan_ @ Sun Jan 13, 2008 12:12 am wrote: I meant that I did not need to store the suits of the cards, however there are still 5 different "types" of each card. Note about sorting: you do not really have to store all the hands to sort them. Consider an array 10x10x10x10 (which is quite reasonable) of counters. You generate a hand and then you can simply increment the associated counter (based on the card values as index values). You can go with your original idea for having the array of 50 cards--sort by value then by suit (you are currently sorting by suit then by value afaik). |
Author: | _Dan_ [ Sun Jan 13, 2008 1:41 am ] |
Post subject: | Re: Question Regarding a Card Combinations Program |
4 Dimensional Arrays :S? You lost me there, but I understand the incrementing part (though I still don't understand how I would use for loops to find each hand). Could someone perhaps give me the code (with comments so I can understand how it works)? |
Author: | OneOffDriveByPoster [ Sun Jan 13, 2008 1:53 am ] |
Post subject: | Re: Question Regarding a Card Combinations Program |
_Dan_ @ Sun Jan 13, 2008 1:41 am wrote: 4 Dimensional Arrays :S? You lost me there, but I understand the incrementing part (though I still don't understand how I would use for loops to find each hand). Your original code (if you fix the typos/whatever makes it slightly off) can find each hand with values in sorted order if you sort set values[] to have 2222233333...BBBBB instead of 23456789AB234... The four dimensional array has a counter for the hand 2222 at a[0][0][0][0] for example. Of course you can use a Map (but some people may not approve). |
Author: | _Dan_ [ Sun Jan 13, 2008 2:02 am ] |
Post subject: | Re: Question Regarding a Card Combinations Program |
Ok I've got everything working, the only problem is that it takes too long to run, even if I only do one Poker-Hand type comparison (i.e. is every hand a flush?). Here's the code I have now: Quote: import java.awt.Color;
import hsa.Console; import java.util.*; /** The "Check" class. * Purpose: * @Author * @Last Updated: */ public class Check { public static boolean isPrime (int value) { if (value < 4) { return true; } int sqrtOfValue = (int) Math.ceil (Math.sqrt (value)); for (int prime = 2 ; prime <= sqrtOfValue ; prime++) { if (value % prime == 0) { return false; } } return true; } public static boolean allDivideC (int fCard, int sCard, int tCard, int foCard, int fiCard, int siCard, int seCard) { int values[] = {fCard, sCard, tCard, foCard, fiCard, siCard, seCard}; for (int f = 0 ; f < 7 ; f++) { for (int s = f + 1 ; s < 7 ; s++) { for (int t = s + 1 ; t < 7 ; t++) { for (int fo = t + 1 ; fo < 7 ; fo++) { int largest = values [f]; if (values [s] > largest) largest = values [s]; if (values [t] > largest) largest = values [t]; if (values [fo] > largest) largest = values [fo]; if (largest % values [f] == 0 && largest % values [s] == 0 && largest % values [t] == 0 && largest % values [fo] == 0) return true; } } } } return false; } public static boolean flushC (int fCard, int sCard, int tCard, int foCard, int fiCard, int siCard, int seCard) { int suits[] = {fCard, sCard, tCard, foCard, fiCard, siCard, seCard}; for (int f = 0 ; f < 7 ; f++) { for (int s = f + 1 ; s < 7 ; s++) { for (int t = s + 1 ; t < 7 ; t++) { for (int fo = t + 1 ; fo < 7 ; fo++) { if (suits [f] == suits [s] && suits [f] == suits [t] && suits [f] == suits [fo]) return true; } } } } return false; } public static boolean straightC (int fCard, int sCard, int tCard, int foCard, int fiCard, int siCard, int seCard) { int values[] = {fCard, sCard, tCard, foCard, fiCard, siCard, seCard}; for (int f = 0 ; f < 7 ; f++) { for (int s = f + 1 ; s < 7 ; s++) { for (int t = s + 1 ; t < 7 ; t++) { for (int fo = t + 1 ; fo < 7 ; fo++) { int[] hand = {values [f], values [s], values [t], values [fo] }; Arrays.sort (hand); if (values [fo] == values [f] + 3 && values [t] == values [f] + 2 && values [s] == values [f] + 1) return true; } } } } return false; } public static boolean isPrimeC (int fCard, int sCard, int tCard, int foCard, int fiCard, int siCard, int seCard) { int values[] = {fCard, sCard, tCard, foCard, fiCard, siCard, seCard}; for (int f = 0 ; f < 7 ; f++) { for (int s = f + 1 ; s < 7 ; s++) { for (int t = s + 1 ; t < 7 ; t++) { for (int fo = t + 1 ; fo < 7 ; fo++) { if (isPrime (values [f]) && isPrime (values [s]) && isPrime (values [t]) && isPrime (values [fo])) return true; } } } } return false; } public static void main (String[] args) { int allDivide = 0; int allPrime = 0; int straight = 0; int flush = 0; int straightFlush = 0; int primeFlush = 0; int divideFlush = 0; int total = 0; int[] suits = new int [50]; for (int counter = 1 ; counter < 6 ; counter++) { for (int increment = 1 ; increment < 11 ; increment++) { suits [increment * counter - 1] = counter; } } int[] values = new int [50]; for (int increment = 0 ; increment < 50 ; increment += 5) { for (int suit = 0 ; suit < 5 ; suit++) { values [increment + suit] = (increment / 5) + 2; } } for (int f = 0 ; f < 50 ; f++) { for (int s = f + 1 ; s < 50 ; s++) { for (int t = s + 1 ; t < 50 ; t++) { for (int fo = t + 1 ; fo < 50 ; fo++) { for (int fi = fo + 1 ; fi < 50 ; fi++) { for (int si = fi + 1 ; si < 50 ; si++) { for (int se = si + 1 ; se < 50 ; se++) { total++; boolean allDivideB = false; boolean allPrimeB = false; boolean straightB = false; boolean flushB = false; if (allDivideC (values [f], values [s], values [t], values [fo], values [fi], values [si], values [se])) allDivideB = true; if (isPrimeC (values [f], values [s], values [t], values [fo], values [fi], values [si], values [se])) allPrimeB = true; if (straightC (values [f], values [s], values [t], values [fo], values [fi], values [si], values [se])) straightB = true; if (flushC (suits [f], suits [s], suits [t], suits [fo], suits [fi], suits [si], suits [se])) flushB = true; if (allDivideB) allDivide++; if (allPrimeB) allPrime++; if (straightB) straight++; if (flushB) flush++; if (flushB && straightB) { straightFlush++; } if (flushB && allPrimeB) { primeFlush++; } if (flushB && allDivideB) { divideFlush++; } } } } } } } } System.out.println ("All Divide: " + allDivide + ", " + (1.0 * allDivide / total * 100) + "%"); System.out.println ("All Prime: " + allPrime + ", " + (1.0 * allPrime / total * 100) + "%"); System.out.println ("Straights: " + straight + ", " + (1.0 * straight / total * 100) + "%"); System.out.println ("Flushes: " + flush + ", " + (1.0 * flush / total * 100) + "%"); System.out.println ("Straight Flushes: " + straightFlush + ", " + (1.0 * straightFlush / total * 100) + "%"); System.out.println ("Prime Flushes: " + primeFlush + ", " + (1.0 * primeFlush / total * 100) + "%"); System.out.println ("Divide Flushes: " + divideFlush + ", " + (1.0 * divideFlush / total * 100) + "%"); System.out.println ("Total: " + total); } // main method } // Check class If you are too confused by it (I used poor variable names and didn't comment) and would like me to add comments and improve my variable names I will. But I need to find a way to GREATLY reduce the amount of time it takes to execute. The program does the following: Generates every possible 7 card combination, generates every possible 4 card combination within that 7 card combination, finds out if that 4 card combination is a special type of hand (i.e. a flush), and if it is increments that type of special hand integer (if it's a flush, increment flush by 1). Example: First Generated 7 card hand (2,2,2,2,2,3,3) -First generated 4 card hand (2,2,2,2) A 7 card hand (2,4,5,6,7,8,11) -A 4 card hand from the 7 card hand (4,7,8,11) |
Author: | OneOffDriveByPoster [ Sun Jan 13, 2008 9:00 am ] |
Post subject: | Re: Question Regarding a Card Combinations Program |
What is this with 7-card hands all of a sudden? Please try to use [syntax="java"] tags to keep your code indentation, etc. |
Author: | _Dan_ [ Sun Jan 13, 2008 11:35 am ] | ||
Post subject: | Re: Question Regarding a Card Combinations Program | ||
Ya I needed 7 card hands, not 4 card hands, the 7 card system I have works though (I tested it). I guess maybe a better way of explaining it is explaining the program I'm making. It's for my Data Management (Probabilities Unit), we have to make Casino games, I chose to make mine on Java, some probabilities are too difficult to figure out by hand (confirmed this with my teacher), hence I'm making a program to calculate them for me. The game is the following: The user is dealt 7 cards. The user must select 4 cards from the 7 cards he is given to create a "hand". This hand is checked to be a flush, straight, among other types of hands. So I need to make the following run Iuno, like 1000-10000 times faster :S? Or maybe I'll just resort to leaving it on overnight to run.
|
Author: | OneOffDriveByPoster [ Sun Jan 13, 2008 12:24 pm ] | ||
Post subject: | Re: Question Regarding a Card Combinations Program | ||
_Dan_ @ Sun Jan 13, 2008 11:35 am wrote:
|
Author: | _Dan_ [ Sun Jan 13, 2008 12:29 pm ] |
Post subject: | Re: Question Regarding a Card Combinations Program |
Um yes? Did I do something wrong with the flush method :S? |
Author: | OneOffDriveByPoster [ Sun Jan 13, 2008 12:32 pm ] |
Post subject: | Re: Question Regarding a Card Combinations Program |
_Dan_ @ Sun Jan 13, 2008 12:29 pm wrote: Um yes? Did I do something wrong with the flush method :S? You don't really need to generate combinations of 4-hands to check that do you? Hint: counters. |
Author: | _Dan_ [ Sun Jan 13, 2008 12:34 pm ] | ||
Post subject: | Re: Question Regarding a Card Combinations Program | ||
I swear I just realized this before I saw you're post :p. Ya ok thanks! It's still nowhere near efficient enough yet though :p. New Method:
|
Author: | OneOffDriveByPoster [ Sun Jan 13, 2008 1:06 pm ] | ||
Post subject: | Re: Question Regarding a Card Combinations Program | ||
_Dan_ @ Sun Jan 13, 2008 12:34 pm wrote: I swear I just realized this before I saw you're post :p. Ya ok thanks! It's still nowhere near efficient enough yet though :p.
What happens when you have all the same suit (for example)?New Method:
|
Author: | _Dan_ [ Sun Jan 13, 2008 1:10 pm ] |
Post subject: | Re: Question Regarding a Card Combinations Program |
Ugh -.-. Sorry I'm being careless, changed to >=. |
Author: | OneOffDriveByPoster [ Sun Jan 13, 2008 1:13 pm ] |
Post subject: | Re: Question Regarding a Card Combinations Program |
_Dan_ @ Sun Jan 13, 2008 1:10 pm wrote: Ugh -.-.
Happens to everyone. I think there are some other minor problems though. You have 5 suits and your suit values are not 0-4 so you need to adjust. It really does save you a lot of trouble use 0-based indexing and start numbering things from 0 (convert on input and output).Sorry I'm being careless, changed to >=. |
Author: | _Dan_ [ Sun Jan 13, 2008 1:16 pm ] |
Post subject: | Re: Question Regarding a Card Combinations Program |
I got an array index out of bounds error before I posted it, so I fixed this :p, I also only checked 4 suits I believe, not 5, I fixed this before my last post as well :p, I'm making the program print out 1 in every 1 million hands it goes through, and I've calculated that it will take 16 minutes to go through all hands, so I guess that's bearable :p. Unless my calculations are incorrect, I think I don't need anymore help for now XD, once again thanks a bunch for all the help. |
Author: | OneOffDriveByPoster [ Sun Jan 13, 2008 1:39 pm ] |
Post subject: | Re: Question Regarding a Card Combinations Program |
_Dan_ @ Sun Jan 13, 2008 1:16 pm wrote: I got an array index out of bounds error before I posted it, so I fixed this :p, I also only checked 4 suits I believe, not 5, I fixed this before my last post as well :p, I'm making the program print out 1 in every 1 million hands it goes through, and I've calculated that it will take 16 minutes to go through all hands, so I guess that's bearable :p. Unless my calculations are incorrect, I think I don't need anymore help for now XD, once again thanks a bunch for all the help. No problem. FYI, I think this is the math way for how many 7-hands has 4-hands that are flushes:
5 suits, 10 values; nCr is how many combinations you can have if you choose r objects from n objects. 5 * (10C4 * 40C3 + 10C5 * 40C2 + 10C6 * 40C1 + 10C7 * 40C0) |
Author: | _Dan_ [ Sun Jan 13, 2008 1:49 pm ] |
Post subject: | Re: Question Regarding a Card Combinations Program |
I already calculated the flushes and prime ones actually (exactly the way you did), it was the other ones that were tricky, for example if you wanted to calculate how many straights occurred, you would need hundreds of cases I believe. Weird... Here is the output I got: All Divide: 29439900, 29.473971911529727% All Prime: 35049250, 35.089813824781444% Straights: 13721875, 13.737755845757697% Flushes: 3337260, 3.3411223374220596% Straight Flushes: 1102220, 1.1034956409609509% Prime Flushes: 1240701, 1.24213691026827% Divide Flushes: 361262, 0.36168010219814106% Total: 99884400 The flush % is incorrect :S. It should be: 11,399,400 and a % of 11.41.. And as for primes. The math would be: i) 4 Primes: 25C4 * 25C3 ii) 5 Primes: 25C5 * 25C2 iii) 6 primes: 25C6 * 25C1 iv) 7 primes: 25C7 * 25C0 i+ii+iii+iv = 49,942,200 With a percentage of 50% Must be something wrong with the method :S. |
Author: | OneOffDriveByPoster [ Sun Jan 13, 2008 1:57 pm ] |
Post subject: | Re: Question Regarding a Card Combinations Program |
_Dan_ @ Sun Jan 13, 2008 1:49 pm wrote: The flush % is incorrect :S.
I had to fix your loop for populating the suits[] array in main().It should be: 11,399,400 and a % of 11.41.. |
Author: | _Dan_ [ Sun Jan 13, 2008 1:58 pm ] | ||
Post subject: | Re: Question Regarding a Card Combinations Program | ||
Oh ok, I'll take a look, I also made the prog more efficient by making the prime hand checker similar to the new flush one. Wait what's wrong with it -.-. Here's my new code by the way:
|
Author: | OneOffDriveByPoster [ Sun Jan 13, 2008 2:06 pm ] |
Post subject: | Re: Question Regarding a Card Combinations Program |
I could tell you, but try printing the array to see first. |
Author: | _Dan_ [ Sun Jan 13, 2008 2:16 pm ] | ||
Post subject: | Re: Question Regarding a Card Combinations Program | ||
Testing the allPrime and flush hands now.
|
Author: | _Dan_ [ Sun Jan 13, 2008 2:35 pm ] |
Post subject: | Re: Question Regarding a Card Combinations Program |
Ok it's working, now I just need to figure out what's wrong with the prime one :S. |
Author: | Tony [ Sun Jan 13, 2008 2:45 pm ] |
Post subject: | RE:Question Regarding a Card Combinations Program |
yes, you don't need any of the for-loops. similarly you don't need 4 for-loops for straightC, one will do just fine (Hint: sort the 7-card pool before the loop) (Hint2: the loop is from 0 to 3) |
Author: | _Dan_ [ Sun Jan 13, 2008 2:51 pm ] | ||
Post subject: | Re: Question Regarding a Card Combinations Program | ||
Arg I forgot about that! I used a similar method for a poker hand problem in comp sci class -.-. Updated. But why are the numbers for the all prime hands incorrect? Also is my straight code correct -.-, it's giving me different numbers.
|
Author: | _Dan_ [ Sun Jan 13, 2008 6:02 pm ] |
Post subject: | Re: Question Regarding a Card Combinations Program |
Damnit, I remember why I needed the flush to go through all possible combinations. I need to also check whether a 4 card hand is both a flush AND a straight/all prime, I also need to check whether a hand is a fractor (all cards in the hand are factors of the largest) AND all prime. Do I have to do the following now?: 1. Make an isStraightFlush method -Make a custom sorting method that sorts the 4 card hands by numerical value, but also changes the location of the suits int the array as well -Sort the hand using the custom sort, check if there are 4 consecutive values and 4 consecutive suits in every possible 4 card combination 2. Make an is flushPrime method -Goes through every possible 4 card hand, checks to see if all of the suits are the same, and all of the values are prime 3. Fractor prime -Goes through every possible 4 card hand, checks to see if the values all divide into the highest AND are prime Or is there a better/easier way of doing this :S (the above will take quite a while...). |
Author: | OneOffDriveByPoster [ Sun Jan 13, 2008 6:55 pm ] |
Post subject: | Re: Question Regarding a Card Combinations Program |
_Dan_ @ Sun Jan 13, 2008 6:02 pm wrote: 2. Make an is flushPrime method
I'll focus on this one as an example. You can use the counter method that was used with plain flushes but only increment when the value is prime. Try to see if thinking differently about the problem helps.
-Goes through every possible 4 card hand, checks to see if all of the suits are the same, and all of the values are prime Also: Quote: Goes through every possible 4 card hand, checks to see if the values all divide into the highest AND are prime ...isn't that just 0? |
Author: | _Dan_ [ Sun Jan 13, 2008 7:13 pm ] |
Post subject: | Re: Question Regarding a Card Combinations Program |
Quote: ...isn't that just 0?
Quadruple Primes . 2,2,2,2 all divide into the highest value, 2, and are all prime :p. Though I could just check if all the values are identical, and that the first value is prime, this method is easy to create. Quote: I'll focus on this one as an example. You can use the counter method that was used with plain flushes but only increment when the value is prime. Try to see if thinking differently about the problem helps.
Good idea XD, ok finished this part. So now all I need is the Straight Flush checking method. |
Author: | OneOffDriveByPoster [ Sun Jan 13, 2008 7:34 pm ] |
Post subject: | Re: Question Regarding a Card Combinations Program |
_Dan_ @ Sun Jan 13, 2008 7:13 pm wrote: So now all I need is the Straight Flush checking method. You don't need to go through all 4-hands with this one either. |
Author: | _Dan_ [ Sun Jan 13, 2008 8:27 pm ] |
Post subject: | Re: Question Regarding a Card Combinations Program |
Do I HAVE to make a custom sort -.-. |
Author: | _Dan_ [ Sun Jan 13, 2008 11:59 pm ] | ||
Post subject: | Re: Question Regarding a Card Combinations Program | ||
The program says there are no straight flushes, what's wrong with my method :S?
|