0

I want something equivalent to the following code. The following code generate poker possible hand patterns.

from itertools import combinations
m = 13
n = 4
x = range(m) * n
y = 5
pattern = set()
for i in combinations(x, y):
    pattern.add(tuple(sorted(i)))

I tried to use itertools.combinations_with_replacement. Not surprisingly there are combinations like (0, 0, 0, 0, 0) or (1, 1, 1, 1, 1). But there are no 5 Queens and 5 Kings in a cards. So I don't want to take 5 same things. How do I implement restricted combinations iterator.

from itertools import combinations_with_replacement
m = 13
n = 4
x = range(m)
y = 5
pattern = []
for i in combinations_with_replacement(x, y):
    pattern.append(i)

I want like the following code.

Pseudo code:

m = 13
n = 4
x = range(m)
y = 5
pattern = []
for i in combinations_with_replacement_restricted(x, y, max=n):
    pattern.append(i)

P.S. Because I'm English learner, please modify my grammar mistakes.

Kei Minagawa
  • 4,395
  • 3
  • 25
  • 43
  • What do you mean by max=n? – Alfred Huang Jul 05 '14 at 00:55
  • @fish_ball It means you can't draw 5 Queen or 5 King or etc. But you can draw at most 4 Queen or 4 King or etc. – Kei Minagawa Jul 05 '14 at 01:10
  • @keimina your current code doesn't draw 5 of the same card. Why would you want "with replacement", that's not how poker hands are dealt. Could you be clearer about what your problems with your current code are? – jonrsharpe Jul 05 '14 at 06:47
  • @jonrsharpe: Yes you are right. I updated my question. I just don't want to use `set` or `if` because I want to calculate the patterns fast. – Kei Minagawa Jul 05 '14 at 09:02
  • @keimina why do you think a `set` isn't fast? Have you got a specific performance problem? Have you profiled it? – jonrsharpe Jul 05 '14 at 09:29
  • @jonrsharpe My real program is not poker but japanese mahjong. I want to calculate `m=9, n=4, x=14` it need 36C14=3796297200 loop calculation if I use `combinations` function. So I want to reduce loop . – Kei Minagawa Jul 05 '14 at 10:18
  • http://stackoverflow.com/q/6284396/3001761 – jonrsharpe Jul 05 '14 at 11:02

2 Answers2

0

After reading the docs: https://docs.python.org/2/library/itertools.html?highlight=combinations#itertools.combinations_with_replacement

I found that a built-in solution for your target don't exists.

So if you want to make this, I think the two solution may be suitable:

[1]. Make all your cards distinct:

from itertools import combinations
m = 13
n = 4
x = range(m * n)
y = 5
pattern = set()
# combinations from range(0, 52)
for i in combinations(x, y):
    # so p/n maps to range(0, 13)
    pattern.add((p / n for p in sorted(i)))

[2]. Exclude all invalid results:

from itertools import combinations
m = 13
n = 4
x = range(m) * n
y = 5
pattern = set()
for i in combinations(x, y):
    if min(i) == max(i):
        continue
    pattern.add(tuple(sorted(i)))
Alfred Huang
  • 17,654
  • 32
  • 118
  • 189
0

You could do this :

import itertools
# each card is a pair (value,  color)
cards = [ (value, color) for value in xrange(13) for color in xrange(4) ] 
# all 5 cards combinations within 52 cards
for hand in itertools.combinations( cards, 5 ) :
  print hand
usual me
  • 8,338
  • 10
  • 52
  • 95