Skip to content

Instantly share code, notes, and snippets.

@PM2Ring
Created May 26, 2018 16:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save PM2Ring/238ea0acc14fed849e708fa904beead8 to your computer and use it in GitHub Desktop.
Save PM2Ring/238ea0acc14fed849e708fa904beead8 to your computer and use it in GitHub Desktop.
Knight tour, using a generator
#!/usr/bin/env python3
''' Knight tour, using recursive backtracking
Version using a generator in a class
Written by PM 2Ring 2018.05.27
'''
class Board:
def __init__(self, size):
self.board = [[0] * size for _ in range(size)]
def __repr__(self):
return '\n'.join([' '.join([f'{u:>2}' for u in row])
for row in self.board])
def __setitem__(self, yx, val):
y, x = yx
self.board[y][x] = val
def __getitem__(self, yx):
y, x = yx
return self.board[y][x]
class KnightTour:
moves = ((-2, -1), (-2, 1), (-1, -2), (-1, 2),
(1, -2), (1, 2), (2, -1), (2, 1))
def __init__(self, size, cy=0, cx=0):
self.size = size
self.hinum = size * size
self.board = Board(size)
self.cy = cy
self.cx = cx
def __iter__(self):
cy, cx = self.cy, self.cx
self.board[cy, cx] = 1
yield from self.solve(cy, cx, 2)
def solve(self, cy, cx, n):
size = self.size
board = self.board
if n > self.hinum:
yield board
else:
for mx, my in self.moves:
y, x = cy + my, cx + mx
if 0 <= y < size and 0 <= x < size and not board[y, x]:
board[y, x] = n
yield from self.solve(y, x, n + 1)
board[y, x] = 0
if __name__ == '__main__':
import sys
size = int(sys.argv[1]) if len(sys.argv) > 1 else 5
cy = int(sys.argv[2]) if len(sys.argv) > 2 else 0
cx = int(sys.argv[3]) if len(sys.argv) > 3 else 0
# We should check that 0 < size and 0 <= cy < size and 0 <= cx < size
for i, b in enumerate(KnightTour(size, cy, cx), 1):
print(i, b, sep='\n', end='\n\n')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment