File: queens.pl

package info (click to toggle)
gprolog 1.4.5.0-3
  • links: PTS
  • area: main
  • in suites: bookworm, bullseye, sid, trixie
  • size: 7,924 kB
  • sloc: ansic: 55,584; perl: 18,501; sh: 3,401; makefile: 1,114; asm: 20
file content (93 lines) | stat: -rw-r--r-- 1,714 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
% generated: 10 November 1989
% option(s):
%
%   (queens) queens_8
%
%   from Sterling and Shapiro, "The Art of Prolog," page 211.
%
%   This program solves the N queens problem:  place N pieces on an N
%   by N rectangular board so that no two pieces are on the same line
%   - horizontal, vertical, or diagonal.  (N queens so placed on an N
%   by N chessboard are unable to attack each other in a single move
%   under the rules of chess.)  The strategy is incremental generate-
%   and-test.
%
%   A solution is specified by a permutation of the list of numbers 1 to
%   N.  The first element of the list is the row number for the queen in
%   the first column, the second element is the row number for the queen
%   in the second column, et cetera.  This scheme implicitly incorporates
%   the observation that any solution of the problem has exactly one queen
%   in each column.
%
%   The program distinguishes symmetric solutions.  For example,
%
%   ?- queens(4, Qs).
%
%   produces
%
%   Qs = [3,1,4,2] ;
%
%   Qs = [2,4,1,3]



queens(ShowResult) :-
	queens(16, R),
	(   ShowResult = true ->
	    write(R), nl
	;   true).


queens(N,Qs):-
	range(1,N,Ns),
	queens(Ns,[],Qs).




queens([],Qs,Qs).

queens(UnplacedQs,SafeQs,Qs):-
	sel(UnplacedQs,UnplacedQs1,Q),
	not_attack(SafeQs,Q),
	queens(UnplacedQs1,[Q|SafeQs],Qs).




not_attack(Xs,X):-
	not_attack(Xs,X,1).

not_attack([],_,_).

not_attack([Y|Ys],X,N):-
	X =\= Y+N,
	X =\= Y-N,
	N1 is N+1,
	not_attack(Ys,X,N1).




sel([X|Xs],Xs,X).

sel([Y|Ys],[Y|Zs],X):-
	sel(Ys,Zs,X).




range(N,N,[N]):- !.

range(M,N,[M|Ns]):-
	M < N,
	M1 is M+1,
	range(M1,N,Ns).


% benchmark interface

benchmark(ShowResult) :-
	queens(ShowResult).

:- include(common).