Reputation: 1334
Let's say there are 9 different cards and 2 different players. When 3 cards are given for each player (a total of 6 cards) out of 9 cards.
How can I generate all combinations of distributing 6 cards to 2 players?
The number of combinations is easily calculated:
number_of_combinations = (9!/(6!*3!)) * (6!/(3!*3!)) = 1680
9!/(6!*3!)
.6!/(3!*3!)
.Therefore, all combinations of distributing 6 cards to 2 players is (9!/(6!*3!)) * (6!/(3!*3!)
.
But generating combinations looks very difficult; this is what I have tried:
comb = itertools.combination([1,2,3,4,5,6,7,8,9], 6)
But there is one problem:
Let's say there are two lists, case1 and case2.
case1 = [1,2,3 ,4,5,6]
case2 = [1,2,4 ,3,5,6]
In my case, I have to handle case1 and case2 differently.
But if I just generate 6 size combinations, I can't do that.
Upvotes: 2
Views: 892
Reputation: 1121774
To produce one dealing, you'd use the random.sample()
function to pick 6 cards at random; give the first 3 to player 1, the remainder to player 2:
dealt_cards = random.sample(deck_of_cards, 6)
player1_hand, player2_hand = dealt_cards[:3], dealt_cards[3:]
To produce all possible combinations then, you'd use itertools.combinations()
with size 6; but you still need to find all possible permutations of dividing those 6 cards over 2 hands that are unique:
for dealt_cards in itertools.combinations(deck_of_cards, 6):
for hand1 in itertools.combinations(dealt_cards, 3):
hand2 = tuple(card for card in dealt_cards if card not in hand1)
so from each dealt combination of 6 cards, all combinations of 3 cards are given to one player, leaving the remaining 3 cards for the other player.
This produces the expected number of solutions:
>>> from itertools import combinations
>>> deck = range(9)
>>> sum(1 for dealt in combinations(deck, 6) for _ in combinations(dealt, 3))
1680
and demo:
>>> for dealt_cards in combinations(deck, 6):
... for hand1 in combinations(dealt_cards, 3):
... hand2 = tuple(card for card in dealt_cards if card not in hand1)
... print hand1, hand2
...
(0, 1, 2) (3, 4, 5)
(0, 1, 3) (2, 4, 5)
(0, 1, 4) (2, 3, 5)
(0, 1, 5) (2, 3, 4)
(0, 2, 3) (1, 4, 5)
# ...
(4, 6, 7) (3, 5, 8)
(4, 6, 8) (3, 5, 7)
(4, 7, 8) (3, 5, 6)
(5, 6, 7) (3, 4, 8)
(5, 6, 8) (3, 4, 7)
(5, 7, 8) (3, 4, 6)
(6, 7, 8) (3, 4, 5)
You could also produce just the player 1 hands, then continue with the remainder of the deck to produce the player 2 hands:
for hand1 in itertools.combinations(deck_of_cards, 3):
for hand2 in itertools.combinations([c for c in deck_of_cards if c not in hand1], 3):
# ...
with the same expected count output and results:
>>> sum(1 for dealt in combinations(deck, 3) for _ in combinations([c for c in deck if c not in dealt], 3))
1680
>>> for hand1 in combinations(deck, 3):
... for hand2 in combinations([c for c in deck if c not in hand1], 3):
... print hand1, hand2
...
(0, 1, 2) (3, 4, 5)
(0, 1, 2) (3, 4, 6)
(0, 1, 2) (3, 4, 7)
(0, 1, 2) (3, 4, 8)
(0, 1, 2) (3, 5, 6)
# ...
(6, 7, 8) (1, 3, 4)
(6, 7, 8) (1, 3, 5)
(6, 7, 8) (1, 4, 5)
(6, 7, 8) (2, 3, 4)
(6, 7, 8) (2, 3, 5)
(6, 7, 8) (2, 4, 5)
(6, 7, 8) (3, 4, 5)
albeit in a different order now.
Upvotes: 4
Reputation: 1217
combinations = itertools.combinations(cards, 6)
This would give you 6 chosen cards, then you need to distribute those 6 cards amongst the 2 players, so:
possibilities = []
for combination in combinations:
hands = []
hand1 = itertools.combinations(combination, 3)
hands.append(hand1)#Hand1
hands.append([x for x in combination if x not in hand1])#Hand2
possibilities.append(hands)
This will generate a list possibilities
for where each item is a list of the 2 different hands.
Upvotes: 1
Reputation: 27283
Just getting all possible combinations of 6 cards won't cut it, since the order in a single player's hand doesn't matter, but it matters who has which cards.
So for all combinations of 3 cards out of 9, choose 3 other cards out of the remaining 6:
from itertools import combinations
def getCardCombinations(cards):
cards = set(cards)
for first in combinations(cards, 3):
for second in combinations(cards - set(first), 3):
yield first, second
cards = [1,2,3,4,5,6,7,8,9]
all_combinations = getCardCombinations(cards)
Upvotes: -1
Reputation: 3198
If I understand you right, you want to get every possible combination of choosing 6 out of 9. Since the order doesn't really matter (we can treat the first 3 as player 1's and the second batch of 3 as player 2's hand), we can just use itertools.combinations
:
from itertools import combinations, izip
hands = combinations(cards, 6)
Am I understanding your question right?
edit: to divide these into two hands of 3 each, you'd use:
player1, player2 = izip(*map(lambda x: (x[:3], x[3:]), combinations(cards, 6)))
Upvotes: -2