Following the book "Structure and interpretation of computer programs" I have tried to implement a functional solution to the problem of N-queens (implemented by the function nQueens
). However, I am not satisfied by the reliance on for loops and the general readability of the code. Could I get your opinion the code?
import functools as fn
def safe(positions, k):
""" Given a list of positions, returns if the queen on the k column
is safe. """
enumeratedPos = tuple(enumerate(positions));
menacesK = fn.partial(menaces, enumeratedPos[k]);
return not any(map(menacesK,
filter(lambda pair: pair[0] != k, enumeratedPos)));
def addNewColumn(positions, n):
""" Given an array of k-length positions maps each position
to n new k+1-length positions by appending numbers from 0 to n-1
Example:
((),) -> ((0), (2) ... (n-1))
((a),(b)) -> ((a, 0), (a,2) ... (a,n-1), (b,0) ... (b,n-1))
"""
for position in positions:
for i in range(0, n):
yield position + (i,);
def menaces(pair1, pair2):
colK, rowK = pair1;
col, row = pair2;
return abs(rowK - row) == abs(colK - col) or rowK == row;
def nQueens(boardSize):
""" Given a dimension boardSize, returns a filter with all the solutions to
n-queens problem where n is boardSize"""
def recur(i):
if (i == 0): return ((),);
safeK = lambda x: safe(x, i-1);
return filter(safeK, addNewColumn(recur(i-1), boardSize));
return recur(boardSize);