Recursive solution

Recursive solution. Should be called using SolveNQueens(int N) method.


public class NQueensAlgorithm
    {
        List<List<string>> ans;
        List<List<char>> board;

        public List<List<string>> SolveNQueens(int N)
        {
            ans = new List<List<string>>();
            board = new List<List<char>>();
            for (int i = 0; i < N; i++)
            {
                board.Add(new List<char>());
                for (int j = 0; j < N; j++)
                {
                    board[i].Add('.');
                }
            }
            Place(0, 0, 0, 0);
            return ans.ToList<List<string>>();
        }

        private void Place(int i, int vert, int ldiag, int rdiag)
        {
            int N = board.Count;
            if (i == N)
            {
                List<string> res = new List<string>();
                for (int row = 0; row < N; row++)
                {
                    string rowStr = new string(board[row].ToArray()); 
                    res.Add(rowStr);
                }
                ans.Add(res);
                return;
            }
            
            for (int j = 0; j < N; j++)
            {
                int vmask = 1 << j;
                int lmask = 1 << (i + j);
                int rmask = 1 << (N - i - 1 + j);
                if ((vert & vmask) + (ldiag & lmask) + (rdiag & rmask) > 0)
                    continue;
                board[i][j] = 'Q';

                Place(i + 1, vert | vmask, ldiag | lmask, rdiag | rmask);

                board[i][j] = '.';
            }
        }
    }

This solution can be called this way:

NQueensAlgorithm algorithm = new();
List<List<string>> result = algorithm.SolveNQueens(N);

Non-recursive solution

This is a non-recursive solution to n-queens problem.

public class NQueensAlgorithm
    {
        private readonly int N;
        private int[] queens;
        private int totalSolutions;
        public NQueensAlgorithm(int N)
        {
            this.N = N;
            queens = new int[N];
            totalSolutions = 0;
        }

        private bool IsQueenSafe(int row, int col)
        {
            for (int r = 0; r < row; r++)
            {
                int c = queens[r];
                if (c == col || Math.Abs(row - r) == Math.Abs(col - c))
                {
                    return false;
                }
            }
            return true;
        }

        private void PrintTheBoard()
        {
            Console.WriteLine("solution:");
            for (int row = 0; row < N; row++)
            {
                char[] line = new char[N];
                for (int i = 0; i < N; i++)
                {
                    line[i] = '.';
                }
                if (row < queens.Length)
                {
                    line[queens[row]] = 'Q';
                }
                Console.WriteLine(new string(line));
            }
        }

        public void Solution()
        {
            Array.Clear(queens, 0, queens.Length);
            int col = 0, row = 0;
            while (true)
            {
                while (col < N && !IsQueenSafe(row, col))
                {
                    col++;
                }
                if (col < N)
                {
                    queens[row] = col;
                    if (row + 1 >= N)
                    {
                        totalSolutions++;
                        PrintTheBoard();
                        queens[row] = 0;
                        col = N;
                    }
                    else
                    {
                        row++;
                        col = 0;
                    }
                }
                if (col >= N)
                {
                    if (row == 0)
                    {
                        Console.WriteLine($"Total solutions: {totalSolutions}");
                        return;
                    }
                    col = queens[--row] + 1;
                }
            }
        }
    }

This algorithm implementation can be called with

NQueensAlgorithm algorithm = new(N);
algorithm.Solution();

Multithread solution

Below is a multithreaded, parallelized solution.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ParallelComputingCS3
{
    public class NQueensAlgorithm
    {
        private readonly int N;
        private int[] queens;
        private int totalSolutions;
        public NQueensAlgorithm(int N)
        {
            this.N = N;
            queens = new int[N];
            totalSolutions = 0;
        }

        private bool IsQueenSafe(int row, int col)
        {
            bool result = true;

            Parallel.For(0, row, new ParallelOptions() { MaxDegreeOfParallelism=2},r =>
            {
                int c = queens[r];
                if (c == col || Math.Abs(row - r) == Math.Abs(col - c))
                {
                    result = false;
                }
            });

            return result;
        }

        private void PrintTheBoard()
        {
            for (int row = 0; row < N; row++)
            {
                char[] line = new char[N];
                for (int i = 0; i < N; i++)
                {
                    line[i] = '.';
                }
                if (row < queens.Length)
                {
                    line[queens[row]] = 'Q';
                }
                Console.WriteLine(new string(line));
            }
        }

        public void Solution()
        {
            Array.Clear(queens, 0, queens.Length);
            int col = 0, row = 0;
            while (true)
            {
                while (col < N && !IsQueenSafe(row, col))
                {
                    col++;
                }
                if (col < N)
                {
                    queens[row] = col;
                    if (row + 1 >= N)
                    {
                        totalSolutions++;
                        //PrintTheBoard();
                        queens[row] = 0;
                        col = N;
                    }
                    else
                    {
                        row++;
                        col = 0;
                    }
                }
                if (col >= N)
                {
                    if (row == 0)
                    {
                        Console.WriteLine($"Total solutions: {totalSolutions}");
                        return;
                    }
                    col = queens[--row] + 1;
                }
            }
        }
    }
}

Sources

https://stackoverflow.com/questions/42318343/avoid-duplicates-in-n-queen-iterative-solutions-no-recursion-allowed

By Owner

Leave a Reply

Your email address will not be published. Required fields are marked *