1
(***********************************************************************)
5
(* Pierre Weis, projet Cristal, INRIA Rocquencourt *)
7
(* Copyright 2001 Institut National de Recherche en Informatique et *)
8
(* en Automatique. All rights reserved. This file is distributed *)
9
(* only by permission. *)
11
(***********************************************************************)
13
(* E I G H T Q U E E N S
15
The Eight Queens Program.
17
How to set n queens on a chessboard of size n such that none
18
can catch one each other.
20
The program computes and prints the set of solutions
21
(without removing symmetrical solutions).
23
Program first compiled in ML V6.2 in 1987.
25
Interesting exercise: change the program such as to be able to compute
26
solutions for sizes greater than a few dozens.
30
(* 1. Resolution of the n queens problem. *)
34
let rec interval n m =
35
if n > m then [] else n :: interval (n + 1) m;;
37
let filter_append p l l0 =
38
let rec filter = function
40
| h :: t -> if p h then h :: filter t else filter t in
43
let rec concmap f = function
45
| h :: t -> f h (concmap f t);;
47
let rec safe x d = function
50
x <> h && x <> h + d && x <> h - d && safe x (d + 1) t;;
54
| h :: t -> safe h 1 t;;
56
let find_solutions size =
57
let line = interval 1 size in
59
if n = 0 then [[]] else
61
(fun b -> filter_append ok (map (fun q -> q :: b) line))
65
(* 2. Printing results. *)
67
let print_solutions size solutions =
68
let sol_num = ref 1 in
71
Printf.printf "\nSolution number %i\n" !sol_num;
72
sol_num := !sol_num + 1;
76
while !count <= size do
77
if !count = line then print_string "Q " else print_string "- ";
84
let print_result size =
85
let solutions = find_solutions size in
86
let sol_num = List.length solutions in
87
Printf.printf "The %i queens problem has %i solutions.\n" size sol_num;
90
print_string "Do you want to see the solutions <n/y> ? "; read_line () in
91
if pr = "y" then print_solutions size solutions;;
93
(* 3. Main program. *)
97
print_string "Chess boards's size ? "; read_int () in
100
if !Sys.interactive then () else queens ();;