3

I found the following C code online a long while ago and have tried implementing this solution in Python. When I compile the C code, I get the expected results; when I run my Python script, I do not receive any output. Below is the C code and my conversion of it to Python. I should note, I'm doing this small project in an effort to learn the Python syntax. From what I can tell in my feeble attempts to debug, the problem lies in my implementation of the diagonalsOK() function. Any advice would be greatly appreciated!

#include <stdio.h>

/* SOLUTION TO EIGHT QUEENS PROBLEM
Author: Eilon Lipton
Date: 1/26/2000
http://www.yoe.org/progchan/start.shtml

All code is copyright (C) Eilon Lipton, 2000
You may use it for educational purposes but please give me credit
if you show the solution to others.
*/

/* Since this program outputs many lines, you should probably redirect its
output to a file like so:
eightq > solution.txt
and then open the file solution.txt in any text editor to see the
results */

/* This function resets the board to an empty board */
void clearboard(int board[8][8])
{
   int i, j;

for (i = 0; i < 8; i++)
  for (j = 0; j < 8; j++)
     board[i][j] = 0;
}


/* This function prints out the board to the screen using a simple diagram 
*/
void printsolution(int board[8][8])
{
   int i, j;

   for (i = 0; i < 8; i++)
   {
      for (j = 0; j < 8; j++)
      {
         if (board[i][j] == 0)
         {
            printf("*");
         }
         else
         {
            printf("Q");
         }
      }

      printf("\n");
   }

   printf("\n");
}


/* Counts how many queens are in a certain row */
int rowOK(int row, int board[8][8])
{
   int i, counter;

   counter = 0;

   for (i = 0; i < 8; i++)
   {
      counter = counter + board[row][i];
   }

       return counter;
    }


/* Counts how many queens are in the two diagonals crossing a certain place 
*/
int diagonalsOK(int row, int column, int board[8][8]){
int i, counter;

counter = 0;

/* This function is a bit tricky:
  We try every diagonal extending no more than 8 spaces in each of the four 
directions
  (down/left, down/right, up/left, and up/right */
for (i = 1; i < 8; i++) {
  if ((row - i) >= 0) {
     if ((column - i) >= 0) {
        counter = counter + board[row - i][column - i];
     }

     if ((column + i) < 8) 
     {
        /* down/right */
        counter = counter + board[row - i][column + i];
     }
  }

  if ((row + i) < 8)   /* check that row is not out of bounds */
  {
     if ((column - i) >= 0)  /* check that column is not out of bounds */
     {
        /* up/left */
        counter = counter + board[row + i][column - i];
     }

     if ((column + i) < 8)  /* check that column is not out of bounds */
     {
        /* up/right*/
        counter = counter + board[row + i][column + i];
     }
  }
}

return counter;
  }


/* This is the most important function, it is described on the web page */
void addqueen(int column, int board[8][8])
{
   int row;

   for (row = 0; row < 8; row++)
   {
      board[row][column] = 1;

      if ((rowOK(row, board) == 1) &&
      (diagonalsOK(row, column, board) == 0))
      {
         if (column == 7)
         {
            printsolution(board);
         }
         else
         {
            addqueen(column + 1, board);
         }
      }

      board[row][column] = 0;
   }
}


/* Main function */
int main()
{
   int board[8][8];

   printf("Meow?\n");
   clearboard(board);
   addqueen(0, board);

   return 0;
}

Python conversion attempt:

board = [[0, 0, 0, 0, 0, 0, 0, 0],
        [0, 1, 0, 0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0, 0, 0, 0],
        [1, 0, 0, 0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0, 0, 0, 0]]

def clearBoard(board):
    for i in range(8):
        for j in range(8):
            board[i][j] = 0

def printBoard(board):
    for i in range(8):
       for j in range(8):
           if board[i][j] == 1:
               print("Q", end="")
           else:
               print("X", end="")
       print("")
    print("")

def rowOK(row, board):
    counter = 0

    for i in range(8):
        counter += board[row][i]
    return counter

def diagsOK(row, col, board):

    counter = 0

    for i in range(8):
        if (row - i) >= 0:
            if (col - i) >= 0:
                counter = counter + board[row - i][col - i]
            if (col + i) < 7:
                counter = counter + board[row - i][col + i]
        if (row + i) < 8:
            if (col - i) >= 0:
                counter = counter + board[row + i][col - i]
            if (col + i) < 8:
                counter = counter + board[row + i][col + i]
    return counter

def addQueen(col, board):
    for row in range(8):
        board[row][col] = 1
        if rowOK(row, board) == 1 & diagsOK(row, col, board) == 0:
        #print("Adding first queen...")
            if col == 7:
                printBoard(board)
            else:
                addQueen(col + 1, board)
        board[row][col] = 0


clearBoard(board)
addQueen(0, board)
blhsing
  • 91,368
  • 6
  • 71
  • 106
Matt
  • 31
  • 2
  • What have you tried and what exactly are you trying to do? `C` code is not helpful here, as the problem is with python. Also, try to keep the code minimal but complete. See https://stackoverflow.com/help/mcve – Eb946207 Dec 10 '18 at 23:42
  • Hi! Thank you for replying . I'm trying to take the solution implemented in C and implement it in Python. I can see how the solution works in C. I'm confused as to why the change into Python syntax doesn't work. – Matt Dec 26 '18 at 18:22

3 Answers3

1

For Starters add print(board) statement after addQueen, and look at that and compare it to when you comment out clearBoard, you can see that the board array you put in seem to clear everything and will get you an output of 0's.

This should give you an idea of what is going on.

Xion
  • 374
  • 2
  • 7
1

You need to check that the columns are OK, also, but how about if you changed addQueen like this:

def addQueen(col, board):
    for row in range(8):
        if rowOK(row, board) == 0 and diagsOK(row, col, board) == 0:
            board[row][col] = 1
            if col == 7:
                printBoard(board)
            else:
                addQueen(col + 1, board)
Tané Tachyon
  • 1,092
  • 8
  • 11
0

Thank you all for your input. I found that the problem had to be with my implementation of the diagsOK() function. I'm still not sure where I went wrong with that function, but I put some thought into how to properly write this and came up with the solution that you see below. There is definitely a much more simple and elegant solution to this problem but I wanted to solve it using what I know how to do. I've tested the solution below and it works. I'm happy :-)

# Matt Lozier's 8 Queens Solution in Python.
#
# Thanks to Eilon Lipton (elipton@microsoft.com) for his logic 
# in implementing the addQueen() function, which I adapted to Python
# from his C implementation.

# This 2D array (or in Python lists of lists) is one solution

board = [[0, 0, 0, 0, 0, 1, 0, 0],
         [0, 0, 0, 1, 0, 0, 0, 0],
         [0, 0, 0, 0, 0, 0, 1, 0],
         [1, 0, 0, 0, 0, 0, 0, 0],
         [0, 0, 0, 0, 0, 0, 0, 1],
         [0, 1, 0, 0, 0, 0, 0, 0],
         [0, 0, 0, 0, 1, 0, 0, 0],
         [0, 0, 1, 0, 0, 0, 0, 0]]

def clearBoard(board):
    for i in range(8):
        for j in range(8):
            board[i][j] = 0

def printBoard(board):
    for i in range(8):
        for j in range(8):
            if board[i][j] == 1:
                print("Q", end="")
            else:
                print("X", end="")
        print("")
    print("")

def checkColsOK(board):
    for i in range(8):
        sum = 0
        for j in range(8):
            sum += board[j][i]
        if sum > 1:
            return 0




def checkRowsOK(board):
    for i in range(8):
        sum = 0
        for j in range (8):
            sum += board[i][j]
        if sum > 1:
            return 0


def checkDiagsOK(board):

# left to right, bottom up
    counter = 8
    sum = 0

    for i in range(8):
        x = i
        y = 0
        for j in range(counter):
            #print(board[y][x], end="")
            sum += board[y][x]
            x += 1
            y +=1
        counter -= 1

        #print("")
        #print("There are ", end="")
        #print(sum, end="")
        #print(" queens in this diagonal.")
        if sum > 1:
            return 0
        sum = 0


# right to left, top down
    counter = 8
    sum = 0

    for i in range(8):
        x = i
        y = 0
        for j in range(counter):
            #print(board[x][y], end="")
            sum += board[x][y]
            x += 1
            y +=1
        counter -= 1

        #print("")
        #print("There are ", end="")
        #print(sum, end="")
        #print(" queens in this diagonal.")

        if sum > 1:
            return 0
        sum = 0


# right to left, bottom up
    counter = 8
    sum = 0

    for i in reversed(range(8)):
        x = i
        y = 0
        for j in range(counter):
            #print(board[x][y], end="")
            sum += board[x][y]
            x -= 1
            y += 1
        counter -= 1

        #print("")
        #print("There are ", end="")
        #print(sum, end="")
        #print(" queens in this diagonal.")

        if sum > 1:
            return 0
        sum = 0

# left to right, top down
    counter = 8
    sum = 0

    for i in range(8):
        x = 7
        y = i
        for j in range(counter):
            #print(board[x][y], end="")
            sum += board[x][y]
            x -= 1
            y += 1
        counter -= 1

        #print("")
        #print("There are ", end="")
        #print(sum, end="")
        #print(" queens in this diagonal.")

        if sum > 1:
            return 0
        sum = 0

def addQueen(board, col):

    row = 0

    for row in range(8):
        board[row][col] = 1
        if (checkRowsOK(board) != 0 and checkDiagsOK(board) != 0):
            if col == 7:
                printBoard(board)
            else:
                addQueen(board, col + 1)
        board[row][col] = 0


clearBoard(board)
addQueen(board, 0)

#if checkDiagsOK(board) != 0:
#    print("Diagonals are OK!")

#if checkRowsOK(board) != 0:
#    print("Rows are OK!")

#if checkRowsOK(board) != 0:
#    print ("Cols are OK!")

#printBoard(board)

#clearBoard(board)

#printBoard(board)
Matt
  • 31
  • 2