Checkout my coding YouTube channel!

Suggestions

TLDR; Not Your Typical Privacy Agreement

  • This chatbot does not store previous messages. It uses ephemeral message storage meaning your conversation will be lost when you close the browser window.
  • Please cross-reference all AI responses because they may be inaccurate but highly unlikely.
  • This chatbot is free of use and does not require a subscription.

Powered by Cohere

My Phone

Samsung Galaxy A56

  • Model: SM-A566B
  • Color: Lightgray
  • Dimensions: 162.2 x 77.5 x 7.4 mm (6.39 x 3.05 x 0.29 in)
  • Weight: 198 g (6.98 oz)
  • Display: Super AMOLED, 120Hz, HDR10+, 1200 nits (HBM), 1900 nits (peak)
  • Resolution: 1080 x 2340 pixels, 19.5:9 ratio (~385 ppi density)
  • OS: Android 15, up to 6 major Android upgrades, One UI 7
  • CPU: Octa-core (1x2.9 GHz Cortex-A720 & 3x2.6 GHz Cortex-A720 & 4x1.9 GHz Cortex-A520)
  • Main Camera: 50 MP, f/1.8, (wide), 1/1.56", 1.0µm, PDAF, OIS, 12 MP, f/2.2, 123˚ (ultrawide), 1/3.06", 1.12µm 5 MP (macro)
  • Selfie Camera: 12 MP, f/2.2, (wide), 4K@30fps, 1080p@30fps, 1080p@60fps (regional availability), 10-bit HDR
  • Battery: 5000 mAh, non-removable

Samsung Galaxy S10e

  • Model: SM-G970F
  • Color: Prism Black
  • Dimensions: 142.2 x 69.9 x 7.9 mm (5.60 x 2.75 x 0.31 in)
  • Weight: 150 g (5.29 oz)
  • Display: Dynamic AMOLED, HDR10+
  • Resolution: 1080 x 2280 pixels, 19:9 ratio (~438 ppi density)
  • OS: Android 9.0 (Pie), upgradable to Android 12, One UI 4.1
  • CPU: Octa-core (2x2.73 GHz Mongoose M4 & 2x2.31 GHz Cortex-A75 & 4x1.95 GHz Cortex-A55) - EMEA/LATAM
  • Main Camera: 12 MP, f/1.5-2.4, 26mm (wide)
  • Selfie Camera: 10 MP, f/1.9, 26mm (wide), 1/3", 1.22µm, dual pixel PDAF
  • Battery: Li-Ion 3100 mAh, non-removable
All Notes

The N-Queens Problem: When Chess Meets Code

Tuesday, January 27, 2026
Author:
Share to Reddit
Share to Facebook
Share to X
Share to LinkedIn
Share to WhatsApp
Share by email
Describing the associated blog post


Imagine this: You’re given a chessboard and N queens. Your mission—should you choose to accept it—is to place all N queens on the board so that no two queens can attack each other.

Simple? Ha. Famous last words.

Queens are powerful pieces. They can attack:

  • Horizontally
  • Vertically
  • Diagonally

So the challenge is to position them such that:

  • No two queens share the same row
  • No two queens share the same column
  • No two queens share the same diagonal

This problem is a legendary example of constraint satisfaction and backtracking in computer science.

Starting Small: The 4-Queens Example

Let’s say N = 4.

A 4×4 chessboard. Four queens. Try placing them randomly and you’ll quickly realize:

  • Brute force (trying everything blindly) is painful 😬
  • Strategy is your best friend

One valid solution looks like this:

. Q . .
. . . Q
Q . . .
. . Q .

Each Q is a queen, and no one is attacking anyone. Peace on the board ✌️

How Do We Solve This in Code?

The most common and elegant approach is backtracking.

Backtracking (a.k.a. “Try, Fail, Undo, Repeat”)

Here’s the idea:

  1. Place a queen in the first row
  2. Move to the next row and try all possible columns
  3. If a placement causes a conflict, backtrack (undo the move)
  4. Continue until:
    • You place all N queens → 🎉 solution found
    • Or you exhaust all options → 😢 no solution

Think of it as politely knocking on doors until you find the right combination.

Key Insight: We Only Need One Queen Per Row

Why?

  • Two queens in the same row = instant fight
  • So we place exactly one queen per row

This simplifies the problem a lot and keeps our sanity intact.

Python Solution 🐍

Here’s a clean Python implementation:

import random

def initialize_random_board(n):
    return [random.randint(0, n-1) for _ in range(n)]

def count_conflicts(board):
    n = len(board)
    conflicts = 0
    for col1 in range(n):
        for col2 in range(col1+1, n):
            row1, row2 = board[col1], board[col2]
            # Check row conflict or diagonal conflict
            if row1 == row2 or abs(row1 - row2) == abs(col1 - col2):
                conflicts += 1
        return conflicts
    
def get_conflicting_queens(board):
    n = len(board)
    conflicting_queens = []
    for col1 in range(n):
        for col2 in range(col1+1, n):
            row1, row2 = board[col1], board[col2]
            if row1 == row2 or abs(row1 - row2) == abs(col1 - col2):
                conflicting_queens.append(col1)
                conflicting_queens.append(col2)
    return list(set(conflicting_queens))

def select_random_conflicting_queen(board):
    conflicts = get_conflicting_queens(board)
    return random.choice(conflicts) if conflicts else None

def move_queen_randomly(board, col):
    n = len(board)
    old_row = board[col]
    new_row = old_row
    while new_row == old_row:
        new_row = random.randint(0, n-1)
    board[col] = new_row

def randomized_n_queens(n, max_iterations=1000):
    board = initialize_random_board(n)
    for iteration in range(max_iterations):
        if count_conflicts(board) == 0:
            return board
        col = select_random_conflicting_queen(board)
        if col is not None:
            move_queen_randomly(board, col)
    return None # No selection found

# Usage
solution = randomized_n_queens(5)
if solution:
    print("Solution found:", solution)
else:
    print("No solution found")

my_board = initialize_random_board(16)
print(my_board)

How This Works

  • board[col] = new_row stores where each queen is placed
  • is_safe checks for the same column and diagonal.
  • backtrack tries every valid possibility row by row.

JavaScript Solution ⚡

Now for the JavaScript fans (yes, you too deserve happiness):

function initializeRandomBoard(n) {
  return new Array(n).fill(null).map((_) => Math.floor(Math.random() * n));
}

function countConflicts(board) {
  const n = board.length;
  let conflicts = 0;
  for (let col1 = 0; col1 < n; col1++) {
    for (let col2 = n; col2 > 0; col2--) {
      let row1 = board[col1];
      let row2 = board[col2];
      // Check row conflict/diagonal conflict
      if (row1 === row2 || Math.abs(row1 - row2) === Math.abs(col1 - col2)) {
        conflicts += 1;
      }
    }
  }
  return conflicts;
}

function getConflictingQueens(board) {
  const n = board.length;
  const conflictingQueens = [];
  for (let col1 = 0; col1 < n; col1++) {
    for (let col2 = n; col1 > 0; col1--) {
      let row1 = board[col1];
      let row2 = board[col2];
      if (row1 === row2 || Math.abs(row1 - row2) === Math.abs(col1 - col2)) {
        conflictingQueens.push(col1);
        conflictingQueens.push(col2);
      }
    }
  }
  return new Set(conflictingQueens);
}

function selectRandomConflictingQueens(board) {
  const conflicts = [...getConflictingQueens(board)];
  return conflicts
    ? conflicts[Math.floor(Math.random() * conflicts.length)]
    : null;
}

function moveQueenRandomly(board, col) {
  const n = board.length;
  let oldRow = board[col];
  let newRow = oldRow;
  while (newRow === oldRow) {
    newRow = Math.floor(Math.random() * n);
  }
  board[col] = newRow;
}

function randomNQueens(n, maxIterations = 1000) {
  const board = initializeRandomBoard(n);
  for (let iteration = 0; iteration < maxIterations; iteration++) {
    if (countConflicts(board) === 0) {
      return board; // Solution found
    }
    const col = selectRandomConflictingQueens(board);
    if (col) {
      moveQueenRandomly(board, col);
    }
  }
  return null;
}

// Usage
const solution = randomNQueens(5)
if(solution){
    console.log("Solution found: ", solution);
} else {
    console.log("No solution found")
}

const myBoard = initializeRandomBoard(16)
console.log(myBoard);

JavaScript Notes

  • Same logic as Python, just JavaScript-ified
  • Spread syntax ([...getConflictingQueens(board)]) copies the solution cleanly
  • No frameworks, no magic, just pure logic ✨

Time Complexity (a Gentle Warning)

The N-Queens problem has exponential complexity.

Roughly:

O(N!)

This means:

  • N = 8 → manageable
  • N = 12 → spicy 🌶️
  • N = 15 → your laptop fan becomes a jet engine ✈️

Don’t worry—this problem is about thinking, not brute power.

Why Is the N-Queens Problem Important?

Because it teaches you:

  • Backtracking
  • Recursion
  • Constraint checking
  • Problem decomposition

It’s also a gateway drug to:

  • Sudoku solvers
  • Scheduling problems
  • AI search algorithms

Basically, it’s chess training for your brain 🧠♛

Final Thoughts

The N-Queens problem is elegant, challenging, and oddly satisfying. It looks innocent, but it rewards structured thinking and patience.

If you can solve N-Queens, you’re well on your way to mastering:

  • Algorithms
  • Recursive thinking
  • “Calm down and undo that” debugging skills 😄

Now go forth, place those queens, and may none of them attack each other.

Happy coding! 🚀

More Articles

Tawanda Andrew Msengezi

Tawanda Andrew Msengezi is a Software Engineer and Technical Writer who writes all the articles on this blog. He has a Bachelor of Science in Computer Information Systems from Near East University. He is an expert in all things web development with a specific focus on frontend development. This blog contains articles about HTML, CSS, JavaScript and various other tech related content.

Comments

No comments for this post yet. Be the first to write a comment.

User Notice

Dear Visitor,

This website stores your color theme preference, you can toggle your theme preference using the lightbulb icon in the top right of the webpage.

Clicking on the robot icon that says 'Chat' in the bottom-left corner will open a chat with an AI assistant. Click the button below to close this message.