Search code examples
pythonalgorithmgraph-algorithmn-queens

I am absolutely stumped on this python programming exercise, can anyone please tell me what is wrong?


I am currently doing a python exercise which, when given a chess board of size n, is to return a solution with the maximum number of queens so that no two queens attack each other. Thus, a solution requires that no two queens share the same row, column, or diagonal.

I am currently able to generate the board, but the problem comes in line 20 of my code, where if bd not in soln. For some reason that I am unable to identify, that line of code does not execute properly and correctly append the correct board to my solution set.

If anyone could help to identify the problem I would be very grateful.

import random

def queensol(n):
    """Find the number of solutions to placing Queens on a chessboard of size n"""
    size = n
    rng = random.Random()
    tries = 0
    bd = list(range(size))
    soln = []

    while True:
        tries += 1
        rng.shuffle(bd)
        correct = 0
        for queen_index in range(size):
            if queen_noclash(bd, queen_index):
                correct += 1
        board_valid = correct == size
        if board_valid:
            if bd not in soln:
                soln.append(bd)
                print(soln)

def no_diagonal(x1, y1, x2, y2):
    dx = abs(x1-x2)
    dy = abs(y1-y2)
    # print('dx',dx)
    # print('dy',dy)
    if dx == dy:
        return False
    else:
        return True


def queen_noclash(bd, queen):
    correct = 0
    for left_queen in range(queen):
        left_queen_x = left_queen
        left_queen_y = bd[left_queen]
        queen_x = queen
        queen_y = bd[queen]
        if no_diagonal(left_queen_x, left_queen_y, queen_x, queen_y):
            correct += 1
    if correct == queen:
        return True
    else:
        return False


queensol(4)

Solution

  • The problem is that the bd is an object. You are appending the same object to the board. So, even though bd changes bd not in soln will always give False since you are comparing the same object. You should use list(bd) to create a new object every time you are appending to soln array. I have fixed this in the below code.

    import random
    
    def queensol(n):
        """Find the number of solutions to placing Queens on a chessboard of size n"""
        size = n
        rng = random.Random()
        tries = 0
        bd = list(range(size))
        soln = []
    
        while True:
            tries += 1
            rng.shuffle(bd)
            correct = 0
            for queen_index in range(size):
                if queen_noclash(bd, queen_index):
                    correct += 1
            board_valid = correct == size
            if board_valid:
                if bd not in soln:
                    soln.append(list(bd))
                    print(soln)
    
    def no_diagonal(x1, y1, x2, y2):
        dx = abs(x1-x2)
        dy = abs(y1-y2)
        # print('dx',dx)
        # print('dy',dy)
        if dx == dy:
            return False
        else:
            return True
    
    
    def queen_noclash(bd, queen):
        correct = 0
        for left_queen in range(queen):
            left_queen_x = left_queen
            left_queen_y = bd[left_queen]
            queen_x = queen
            queen_y = bd[queen]
            if no_diagonal(left_queen_x, left_queen_y, queen_x, queen_y):
                correct += 1
        if correct == queen:
            return True
        else:
            return False
    
    
    queensol(4)