Skip to main content
edited tags
Link
200_success
  • 144.2k
  • 22
  • 188
  • 473
Source Link
Zanzag
  • 392
  • 3
  • 8

Functional n-queens

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);