Search code examples
pythonlistnumbersitems

How to check if there are 3 or 4 or 5 consecutive numbers in a list with 6 items?


How to check if there are 3 or 4 or 5 or 6 consecutive numbers in a list with 6 items?

I’m using python. I tried to generate combinations of numbers 1-42. I have 5million+ combinations. I am trying to reduce the number of combinations by removing the ones that have 3-6 consecutive numbers.

Given lists:

(5,8,12,28,29,30) has 3 consecutive

(1,8,9,10,11,23) has 4 consecutive

(2,12,13,14,15,16) has 5 consecutive

(3,4,5,6,7,8) has 6 consecutive

(3,9,11,14,15,21) has 2 consecutive

(2,5,7,12,21,34)

(3,5,8,10,12,34)

By removing the lists that have 3-6 consecutive numbers the output should be:

(3,9,11,14,15,21)

(2,5,7,12,21,34)

(3,5,8,10,12,34)

Solution

  • Here's what you're asking for:

    import itertools
    
    def maxRunSize(t):
        return 1+max(len(tuple(g)) if k else 0 for k,g in itertools.groupby(zip(t, t[1:]), key=lambda t: t[1]-t[0]==1))
    

    Output:

    In [87]: maxRunSize((5,8,12,28,29,30))                                                                                                                                                                                                                                        
    Out[87]: 3
    
    In [88]: maxRunSize((1,8,9,10,11,23))                                                                                                                                                                                                                                         
    Out[88]: 4
    
    In [89]: maxRunSize((2,12,13,14,14,16))                                                                                                                                                                                                                                       
    Out[89]: 3
    
    In [90]: maxRunSize((2,12,13,14,15,16))                                                                                                                                                                                                                                       
    Out[90]: 5
    
    In [91]: maxRunSize((3,4,5,6,7,8))                                                                                                                                                                                                                                            
    Out[91]: 6
    

    But if you'd rather just generate combinations without long runs (so that you won't have to filter them out later), check this out:

    import random
    def generate(n, k, window):
        """
        Generate n-choose-k combinations in [1,n] such that there is no window-length of consecutive numbers
        """
    
        answer = []
        while True:
            if len(answer) >= window:
                if answer[-window:] == list(range(answer[-window], window+1)):
                    answer = []
                elif len(answer) == k:
                    yield answer
                    answer = []
            elif len(answer) == window-1:
                if answer[1-window:] == list(range(answer[1-window], window)):
                    answer.append(random.choice([i for i in range(1,n+1) if i!=answer[-1]+1]))
            else:
                answer.append(random.choice(range(1,n+1)))