vxs8122
vxs8122

Reputation: 844

Listing all possible sequence of cards in hand

By definition, a sequence is a combination of at least three cards that are in a numerical sequence (consecutive numbers). Suits does not matter. Example: 6♥ 7♥ 8♠ or 3♦ 4♥ 5♦ 6♥

In this partial code, I can list all possible combination of only three cards. Assume the cards in self.hand is already sorted in term of ranks.

if len(self.hand) > 2:
    for i in range(len(self.hand)-2):
        for j in range(i+1,len(self.hand)-1):
            for k in range(j+1,len(self.hand)):
                combo = Combo([self.hand[i],self.hand[j],self.hand[k]])
                if combo.isSequence():
                    possibleCombos.append(combo)

I could repeat this similar code for sequence of 4 cards, 5 cards, etc. but is there a more compact way to do this? I couldn't find a way to control a number of loops as the sequence gets longer.

Upvotes: 1

Views: 420

Answers (1)

Tagc
Tagc

Reputation: 9076

By definition, a sequence is a combination of at least three cards that are in a numerical sequence.

I believe this should work. I assume a set of 5 distinct cards (1-5) with no suit. I also assume that the numbers just have to be in ascending order, which I'll need clarification on (thanks for asking asongtoruin).

import itertools 


def all_card_sequences_of_size(cards, n):
    return itertools.combinations(cards, n)  


if __name__ == '__main__':
    cards = [i + 1 for i in range(5)]
    print(list(all_card_sequences_of_size(cards, 3)))
    print(list(all_card_sequences_of_size(cards, 4)))

Output

[(1, 2, 3), (1, 2, 4), (1, 2, 5), (1, 3, 4), (1, 3, 5), (1, 4, 5), (2, 3, 4), (2, 3, 5), (2, 4, 5), (3, 4, 5)]
[(1, 2, 3, 4), (1, 2, 3, 5), (1, 2, 4, 5), (1, 3, 4, 5), (2, 3, 4, 5)]

Assuming that you do need the sequences to be consecutive, here's a solution for that:

import itertools

def is_sequence_consecutive(sequence):
    return all(a == b - 1 for a, b in zip(sequence[:-1], sequence[1:]))


def all_card_sequences_of_size(cards, n):
    for sequence in itertools.combinations(cards, n):
        if is_sequence_consecutive(sequence):
            yield sequence


if __name__ == '__main__':
    cards = [i + 1 for i in range(5)]
    print(list(all_card_sequences_of_size(cards, 3)))
    print(list(all_card_sequences_of_size(cards, 4)))

Output

[(1, 2, 3), (2, 3, 4), (3, 4, 5)]
[(1, 2, 3, 4), (2, 3, 4, 5)]

To get all possible consecutive sequences for n number of cards (n >= 3):

import itertools


def is_sequence_consecutive(sequence):
    return all(a == b - 1 for a, b in zip(sequence[:-1], sequence[1:]))


def all_card_sequences_of_size(cards, n):
    for sequence in itertools.combinations(cards, n):
        if is_sequence_consecutive(sequence):
            yield sequence


def all_card_sequences(cards):
    for i in range(3, len(cards) + 1):
        yield from all_card_sequences_of_size(cards, i)


if __name__ == '__main__':
    cards = [i + 1 for i in range(5)]
    print(list(all_card_sequences(cards)))

Output

[(1, 2, 3), (2, 3, 4), (3, 4, 5), (1, 2, 3, 4), (2, 3, 4, 5), (1, 2, 3, 4, 5)]

Upvotes: 4

Related Questions