Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 43 additions & 0 deletions Backtracking/NQueens.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
(* N-Queens Problem Solver (Backtracking) in OCaml.
This code counts all solutions to the N-Queens problem using backtracking
and **persistent sets** for efficient state management.
*)

module S = Set.Make(struct type t = int let compare = compare end)

(** Applies a function to every element in a set, returning a new set.
Used to **shift** diagonal threat columns for the next row. *)
let map f s = S.fold (fun x s -> S.add (f x) s) s S.empty

(** Creates the initial set of columns: {0, 1, ..., N-1}. *)
let rec upto n = if n < 0 then S.empty else S.add n (upto (n-1))

(** Finds the total number of solutions compatible with the current state.
This is the core **backtracking** function.

@param cols Remaining **available** columns for subsequent rows.
@param d1 Columns threatened by **left diagonals** (shifted by +1).
@param d2 Columns threatened by **right diagonals** (shifted by -1).
*)
let rec count cols d1 d2 =
if S.is_empty cols then
(* Base case: All N queens are placed successfully. *)
1
else
(* Set of **safe** columns for the current row: cols \ d1 \ d2 *)
S.fold
(fun c res ->
(* Persistence: New state sets are created for the recursive call.
Original d1, d2 are preserved for the next iteration of the fold. *)
let d1 = map succ (S.add c d1) in (* New left-diagonal threats *)
let d2 = map pred (S.add c d2) in (* New right-diagonal threats *)

(* Recurse to the next row with the updated state. *)
res + count (S.remove c cols) d1 d2)
(S.diff (S.diff cols d1) d2)
0 (* Initial solution count *)

(* Main execution: Reads N from command line and prints the result. *)
let () =
let n = int_of_string Sys.argv.(1) in
Format.printf "%d@." (count (upto (n - 1)) S.empty S.empty)