Search code examples
pythoncombinationspython-itertools

reduce a combination eliminating rows with more than two consecutives


im trying to have this working and printing to a file because is faster, but I dont know why it prints 7 lines from each result ending with a enormous file, what I am doing wrong? I want 7 numbers selected from 1 to 56 with no more than 2 consecutives in each iteration, a permutation gives something like 230 million results so I think this must be smaller, Thank you!

from itertools import combinations, groupby
from operator import itemgetter
f= open('7.txt','w')

data = [1,2,3,4,5,6,7,8,9,10,11,
        12,13,14,15,16,17,18,19,
        20,21,22,23,24,25,26,27,
        28,29,30,31,32,33,34,35,
        36,37,38,39,40,41,42,43,
        44,45,46,47,48,49,50,51,
        52,53,54,55,56]

def find_consecutive(lst, min_string=3):
    for k, g in groupby(enumerate(lst), lambda (i,x):i-x):
        num_string = map(itemgetter(1), g)
        if len(num_string) >= 3:
            yield num_string

for i in combinations(data, 7):
    if not any(find_consecutive(i, min_string=3)):
            for x in i:
                f.write(str(i))
                f.write('\n')
f.close()

Solution

  • your code can be simplified like below.

    Changes:

    • please note that I have replaced file write code with print for ease of testing
    • I have changed your data to range
    • Changed has_consecutive_number function
    • write x to file instead of i
    from itertools import combinations, groupby, count
    from operator import itemgetter
    
    data = range(1,57)
    
    def has_consecutive_number(lst, min_string=3):
        lst = sorted(lst)
        consecutives = [i-j for i,j in zip(lst[1:], lst[:-1])].count(1)
        if consecutives<min_string:
            return True
    
        return False
    
    with open('7.txt','w') as f:
        for i in combinations(data, 7):
            if has_consecutive_number(i, min_string=3):
                print(i)
                for x in i:
                    print(x)