Как проверить, есть ли 3, 4 или 5 последовательных чисел в списке из 6 пунктов?

#python #list #numbers #items

Вопрос:

Как проверить, есть ли 3 или 4, 5 или 6 последовательных чисел в списке из 6 пунктов?

Я использую python . Я попытался сгенерировать комбинации чисел 1-42. У меня есть более 5 миллионов комбинаций. Я пытаюсь уменьшить количество комбинаций, удалив те, в которых есть 3-6 последовательных чисел.

Приведенные списки:

 (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)
 

При удалении списков, содержащих 3-6 последовательных чисел, вывод должен быть:

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

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

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

Комментарии:

1. Что вы пробовали до сих пор?

Ответ №1:

Вот о чем ты просишь:

 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))
 

Выход:

 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
 

Но если вы предпочитаете просто генерировать комбинации без длительных запусков (чтобы вам не пришлось отфильтровывать их позже), ознакомьтесь с этим:

 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)))

 

Комментарии:

1. Кажется, это работает. Я бы просто взял те, у которых 3-6 последовательных чисел, а затем удалил их. Выведите остальные списки. Не могли бы вы, пожалуйста, объяснить код? Для меня это новый урок. Огромное спасибо.

2. Код генерирует и выдает комбинации размера k (в вашем случае 6). Однако, поскольку он генерирует жизнеспособную комбинацию, он выглядит как последние window-1 элементы и проверяет, образуют ли они допустимый прогон. Если это так, то следующее число,которое он генерирует, все еще находится в интервале [1, n], но не включает в себя одно число, которое продолжило бы выполнение

Ответ №2:

Если все последовательности содержат ровно 6 чисел в строго возрастающем порядке, вы можете использовать быстрый и простой тест:

 if any(x[i] 2 == x[i 2] for i in range(4)):
    # ... remove x ...