From f5450d2a4d15301d1c07d1d108d2410ea8bc4e39 Mon Sep 17 00:00:00 2001 From: shimmer12 Date: Wed, 8 Oct 2025 22:27:09 +0530 Subject: [PATCH] added backtracking/NQueen solution --- Backtracking/NQueens.ml | 43 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 Backtracking/NQueens.ml diff --git a/Backtracking/NQueens.ml b/Backtracking/NQueens.ml new file mode 100644 index 0000000..a80ca64 --- /dev/null +++ b/Backtracking/NQueens.ml @@ -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) \ No newline at end of file