python分发扑克牌_python – 生成所有5张牌扑克牌

你的整体方法是健全的。我很确定问题在于你的make_canonical函数。您可以尝试打印出num_cards设置为3或4的手,并查找您错过的等效。

我发现一个,但可能有更多:

# The inputs are equivalent and should return the same value

print make_canonical([8, 12 | 1]) # returns [8, 13]

print make_canonical([12, 8 | 1]) # returns [12, 9]

作为参考,下面是我的解决方案(在查看您的解决方案之前开发的)。我使用深度优先搜索,而不是广度优先搜索。此外,我不是写一个函数来将手转换为规范形式,而是写了一个函数来检查手是否是规范的。如果它不是规范,我跳过它。我定义了rank = card%13和suit = card / 13.这些差别都不重要。

import collections

def canonical(cards):

"""

Rules for a canonical hand:

1. The cards are in sorted order

2. The i-th suit must have at least many cards as all later suits. If a

suit isn't present, it counts as having 0 cards.

3. If two suits have the same number of cards, the ranks in the first suit

must be lower or equal lexicographically (e.g., [1, 3] <= [2, 4]).

4. Must be a valid hand (no duplicate cards)

"""

if sorted(cards) != cards:

return False

by_suits = collections.defaultdict(list)

for suit in range(0, 52, 13):

by_suits[suit] = [card%13 for card in cards if suit <= card < suit+13]

if len(set(by_suits[suit])) != len(by_suits[suit]):

return False

for suit in range(13, 52, 13):

suit1 = by_suits[suit-13]

suit2 = by_suits[suit]

if not suit2: continue

if len(suit1) < len(suit2):

return False

if len(suit1) == len(suit2) and suit1 > suit2:

return False

return True

def deal_cards(permutations, n, cards):

if len(cards) == n:

permutations.append(list(cards))

return

start = 0

if cards:

start = max(cards) + 1

for card in range(start, 52):

cards.append(card)

if canonical(cards):

deal_cards(permutations, n, cards)

del cards[-1]

def generate_permutations(n):

permutations = []

deal_cards(permutations, n, [])

return permutations

for cards in generate_permutations(5):

print cards

它生成正确的排列数:

Cashew:~/$ python2.6 /tmp/cards.py | wc

134459

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值