Initial data commit

This commit is contained in:
Ingy döt Net 2023-07-01 11:58:00 -04:00
parent 72d218235f
commit f23f22d71c
199087 changed files with 3378941 additions and 0 deletions

View file

@ -0,0 +1,21 @@
solution([]).
solution([X/Y|Others]) :-
solution(Others),
member(Y, [1,2,3,4,5,6,7,8]),
noattack(X/Y, Others).
noattack(_,[]).
noattack(X/Y,[X1/Y1|Others]) :-
Y =\= Y1,
Y1 - Y =\= X1 - X,
Y1 - Y =\= X - X1,
noattack(X/Y,Others).
member(Item,[Item|Rest]).
member(Item,[First|Rest]) :-
member(Item,Rest).
template([1/Y1,2/Y2,3/Y3,4/Y4,5/Y5,6/Y6,7/Y7,8/Y8]).

View file

@ -0,0 +1,28 @@
solution(Queens) :-
permutation([1,2,3,4,5,6,7,8], Queens),
safe(Queens).
permutation([],[]).
permutation([Head|Tail],PermList) :-
permutation(Tail,PermTail),
del(Head,PermList,PermTail).
del(Item,[Item|List],List).
del(Item,[First|List],[First|List1]) :-
del(Item,List,List1).
safe([]).
safe([Queen|Others]) :-
safe(Others),
noattack(Queen,Others,1).
noattack(_,[],_).
noattack(Y,[Y1|Ylist],Xdist) :-
Y1-Y=\=Xdist,
Y-Y1=\=Xdist,
Dist1 is Xdist + 1,
noattack(Y,Ylist,Dist1).

View file

@ -0,0 +1,20 @@
solution(Ylist) :-
sol(Ylist,[1,2,3,4,5,6,7,8],
[1,2,3,4,5,6,7,8],
[-7,-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6,7],
[2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]).
sol([],[],[],Du,Dv).
sol([Y|Ylist],[X|Dx1],Dy,Du,Dv) :-
del(Y,Dy,Dy1),
U is X-Y,
del(U,Du,Du1),
V is X+Y,
del(V,Dv,Dv1),
sol(Ylist,Dx1, Dy1,Du1,Dv1).
del(Item,[Item|List],List).
del(Item,[First|List],[First|List1]) :-
del(Item,List,List1).

View file

@ -0,0 +1,16 @@
:- initialization(main).
queens(N,Qs) :- bagof(X, between(1,N,X), Xs), place(Xs,[],Qs).
place(Xs,Qs,Res) :-
Xs = [] -> Res = Qs
; select(Q,Xs,Ys), not_diag(Q,Qs,1), place(Ys,[Q|Qs],Res)
.
not_diag(_, [] , _).
not_diag(Q, [Qh|Qs], D) :-
abs(Q - Qh) =\= D, D1 is D + 1, not_diag(Q,Qs,D1).
main :- findall(Qs, (queens(8,Qs), write(Qs), nl), _), halt.

View file

@ -0,0 +1,23 @@
% 8 queens problem.
% q(Row) represents a queen, allocated one per row. No rows ever clash.
% The columns are chosen iteratively from available columns held in a
% list, reduced with each allocation, so we need never check verticals.
% For diagonals, we check prior to allocation whether each newly placed
% queen will clash with any of the prior placements. This prevents
% most invalid permutations from ever being attempted.
can_place(_, []) :- !. % success for empty board
can_place(q(R,C),Board) :- % check diagonals against allocated queens
member(q(Ra,Ca), Board), abs(Ra-R) =:= abs(Ca-C), !, fail.
can_place(_,_). % succeed if no diagonals failed
queens([], [], Board, Board). % found a solution
queens([q(R)|Queens], Columns, Board, Solution) :-
nth0(_,Columns,C,Free), can_place(q(R,C),Board), % find all solutions
queens(Queens,Free,[q(R,C)|Board], Solution). % recursively
queens :-
findall(q(N), between(0,7,N), Queens), findall(N, between(0,7,N), Columns),
findall(B, queens(Queens, Columns, [], B), Boards), % backtrack over all
length(Boards, Len), writef('%w solutions:\n', [Len]), % Output solutions
member(R,Boards), reverse(R,Board), writef(' - %w\n', [Board]), fail.
queens.

View file

@ -0,0 +1,5 @@
not_diagonal(X, N) :-
maplist(plus, X, N, Z1), maplist(plus, X, Z2, N), is_set(Z1), is_set(Z2).
queens(N, Qs) :-
numlist(1, N, P), findall(Q, (permutation(P, Q), not_diagonal(Q, P)), Qs).

View file

@ -0,0 +1,10 @@
% John Devou: 26-Nov-2021
% Short solution to use on https://swish.swi-prolog.org/.
% Works fast for n ≤ 17.
:- use_rendering(chess).
q(_,0,[],[]).
q(N,R,[(R,C)|Qs],[C|Cs]):- R > 0, S is R-1, q(N,S,Qs,Cs), between(1,N,C),
not((member((U,V),Qs), (V =:= C; R-U =:= abs(C-V)))).
q(N,X):- q(N,N,_,X).

View file

@ -0,0 +1,72 @@
:- use_module(library(clpfd)).
% DOC: http://www.pathwayslms.com/swipltuts/clpfd/clpfd.html
length_(Length, List) :- length(List, Length).
applyConstraints([]).
applyConstraints([ Q | Queens ]) :-
checkConstraints(Q, Queens),
applyConstraints(Queens).
checkConstraints(_, []).
checkConstraints([Row0, Col0], [ [Row1, Col1] | Queens]) :-
Row0 #\= Row1, % No two queens on same row
Col0 #\= Col1, % No two queens on same columns
Row0 + Col0 #\= Row1 + Col1, % Down diagonals: [8,1], [7,2], [6,3]
Row0 - Col0 #\= Row1 - Col1, % Up diagonals: [1,1], [2,2], [3,3]
checkConstraints([Row0,Col0], Queens).
% Optimization: pre-assign each queen to a named row
optimizeQueens(Queens) :- optimizeQueens(Queens, 1).
optimizeQueens([],_).
optimizeQueens([[Row,_] | Queens], Index) :-
Row #= Index,
NextIndex is Index + 1,
optimizeQueens(Queens, NextIndex).
nqueens(N, Queens) :-
% Function Preconditions
N > 0,
% Create 2D Datastructure for Queens
length(Queens, N), maplist(length_(2), Queens),
flatten(Queens, QueenArray),
% Queens coords must be in range
QueenArray ins 1..N,
% Apply Constraints
optimizeQueens(Queens),
applyConstraints(Queens),
% Solve
label(QueenArray),
true.
all_nqueens(N) :- all_nqueens(N, _).
all_nqueens(N, Solutions) :-
findall(Queens, (nqueens(N,Queens), write(Queens), nl), Solutions),
length(Solutions,Count),
write(Count), write(' solutions'), nl,
Count #>= 1.
print_nqueens_all(N) :- all_nqueens(N, Solutions), print_nqueens(N, Solutions).
print_nqueens(N) :- nqueens(N, Queens), print_board(N, Queens).
print_nqueens(N, [Queens|Remaining]) :- print_count(Remaining), print_board(N, Queens), print_nqueens(N, Remaining).
print_nqueens(_, []).
print_count(Remaining) :- length(Remaining, Count), Count1 is Count + 1, nl, write('# '), write(Count1), nl.
print_board(N, [[_,Q] | Queens]) :- print_line(N, '-'), print_line(N, '|', Q), print_board(N, Queens).
print_board(N, []) :- print_line(N, '-').
print_line(0,'-') :- write('-'), nl.
print_line(N,'-') :- write('----'), N1 is N-1, print_line(N1,'-').
print_line(0,'|',_) :- write('|'), nl.
print_line(N,'|',Q) :- write('|'), (( Q == N ) -> write(' Q ') ; write(' ')), N1 is N-1, print_line(N1,'|',Q).
%:- initialization main.
main :-
print_nqueens_all(8).