How about using fractal / recursive? This implementation divides the rectangular range into four quadrants, then gives points from each quadrant. This means that neighboring points in the sequence differ by at least a quadrant.
#python3 import sys import itertools def interleave(*iters): for elements in itertools.zip_longest(*iters): for element in elements: if element != None: yield element def scramblerange(begin, end): width = end - begin if width == 1: yield begin else: first = scramblerange(begin, int(begin + width/2)) second = scramblerange(int(begin + width/2), end) yield from interleave(first, second) def scramblerectrange(top=0, left=0, bottom=1, right=1, width=None, height=None): if width != None and height != None: yield from scramblerectrange(bottom=height, right=width) raise StopIteration if right - left == 1: if bottom - top == 1: yield (left, top) else: for y in scramblerange(top, bottom): yield (left, y) else: if bottom - top == 1: for x in scramblerange(left, right): yield (x, top) else: halfx = int(left + (right - left)/2) halfy = int(top + (bottom - top)/2) quadrants = [ scramblerectrange(top=top, left=left, bottom=halfy, right=halfx), reversed(list(scramblerectrange(top=top, left=halfx, bottom=halfy, right=right))), scramblerectrange(top=halfy, left=left, bottom=bottom, right=halfx), reversed(list(scramblerectrange(top=halfy, left=halfx, bottom=bottom, right=right))) ] yield from interleave(*quadrants) if __name__ == '__main__': letters = 'abcdefghijklmnopqrstuvwxyz' output = [] indices = dict() for i, pt in enumerate(scramblerectrange(width=11, height=5)): indices[pt] = i x, y = pt output.append(letters[x] + str(y)) table = [[indices[x,y] for x in range(11)] for y in range(5)] print(', '.join(output)) print() pad = lambda i: ' ' * (2 - len(str(i))) + str(i) header = ' |' + ' '.join(map(pad, letters[:11])) print(header) print('-' * len(header)) for y, row in enumerate(table): print(pad(y)+'|', ' '.join(map(pad, row)))
Outputs:
a0, i1, a2, i3, e0, h1, e2, g4, a1, i0, a3, k3, e1, h0, d4, g3, b0, j1, b2, i4, d0, g1, d2, h4, b1, j0, b3, k4, d1, g0, d3, f4, c0, k1, c2, i2, c1, f1, a4, h2, k0, e4, j3, f0, b4, h3, c4, j2, e3, g2, c3, j4, f3, k2, f2 | abcdefghijk ----------------------------------- 0| 0 16 32 20 4 43 29 13 9 25 40 1| 8 24 36 28 12 37 21 5 1 17 33 2| 2 18 34 22 6 54 49 39 35 47 53 3| 10 26 50 30 48 52 15 45 3 42 11 4| 38 44 46 14 41 31 7 23 19 51 27