You can throw recursion on the task (this can be massaged a little):
def jump(n, min_gap, right_bound, so_far=None): if so_far is None: so_far = [] if n == 0: yield so_far else: min_x0 = 0 if not so_far else so_far[-1] + min_gap for i in range(min_x0, right_bound): for child in jump(n-1, min_gap, right_bound, so_far+[i]): yield child
which gives
>>> pprint.pprint(list(jump(3, 1, 5))) [[0, 1, 2], [0, 1, 3], [0, 1, 4], [0, 2, 3], [0, 2, 4], [0, 3, 4], [1, 2, 3], [1, 2, 4], [1, 3, 4], [2, 3, 4]] >>> pprint.pprint(list(jump(3, 2, 5))) [[0, 2, 4]]
and matches the results of @gboffi:
>>> list(jump(3, 5, 20)) == [[x,y,z] for x in range(20) for y in range(x+5,20) for z in range(y+5,20)] True >>> list(jump(4,5,30)) == eval(apart(30,5,4)) True