Data commit

This commit is contained in:
Ingy döt Net 2023-07-01 11:58:00 -04:00
parent 7387c8f97b
commit cb5bb5e222
199093 changed files with 3378972 additions and 0 deletions

View file

@ -0,0 +1,80 @@
% N is the number of lines of the chessboard
knight(N) :-
Max is N * N,
length(L, Max),
knight(N, 0, Max, 0, 0, L),
display(N, 0, L).
% knight(NbCol, Coup, Max, Lig, Col, L),
% NbCol : number of columns per line
% Coup : number of the current move
% Max : maximum number of moves
% Lig/ Col : current position of the knight
% L : the "chessboard"
% the game is over
knight(_, Max, Max, _, _, _) :- !.
knight(NbCol, N, MaxN, Lg, Cl, L) :-
% Is the move legal
Lg >= 0, Cl >= 0, Lg < NbCol, Cl < NbCol,
Pos is Lg * NbCol + Cl,
N1 is N+1,
% is the place free
nth0(Pos, L, N1),
LgM1 is Lg - 1, LgM2 is Lg - 2, LgP1 is Lg + 1, LgP2 is Lg + 2,
ClM1 is Cl - 1, ClM2 is Cl - 2, ClP1 is Cl + 1, ClP2 is Cl + 2,
maplist(best_move(NbCol, L),
[(LgP1, ClM2), (LgP2, ClM1), (LgP2, ClP1),(LgP1, ClP2),
(LgM1, ClM2), (LgM2, ClM1), (LgM2, ClP1),(LgM1, ClP2)],
R),
sort(R, RS),
pairs_values(RS, Moves),
move(NbCol, N1, MaxN, Moves, L).
move(NbCol, N1, MaxN, [(Lg, Cl) | R], L) :-
knight(NbCol, N1, MaxN, Lg, Cl, L);
move(NbCol, N1, MaxN, R, L).
%% An illegal move is scored 1000
best_move(NbCol, _L, (Lg, Cl), 1000-(Lg, Cl)) :-
( Lg < 0 ; Cl < 0; Lg >= NbCol; Cl >= NbCol), !.
best_move(NbCol, L, (Lg, Cl), 1000-(Lg, Cl)) :-
Pos is Lg*NbCol+Cl,
nth0(Pos, L, V),
\+var(V), !.
%% a legal move is scored with the number of moves a knight can make
best_move(NbCol, L, (Lg, Cl), R-(Lg, Cl)) :-
LgM1 is Lg - 1, LgM2 is Lg - 2, LgP1 is Lg + 1, LgP2 is Lg + 2,
ClM1 is Cl - 1, ClM2 is Cl - 2, ClP1 is Cl + 1, ClP2 is Cl + 2,
include(possible_move(NbCol, L),
[(LgP1, ClM2), (LgP2, ClM1), (LgP2, ClP1),(LgP1, ClP2),
(LgM1, ClM2), (LgM2, ClM1), (LgM2, ClP1),(LgM1, ClP2)],
Res),
length(Res, Len),
( Len = 0 -> R = 1000; R = Len).
% test if a place is enabled
possible_move(NbCol, L, (Lg, Cl)) :-
% move must be legal
Lg >= 0, Cl >= 0, Lg < NbCol, Cl < NbCol,
Pos is Lg * NbCol + Cl,
% place must be free
nth0(Pos, L, V),
var(V).
display(_, _, []).
display(N, N, L) :-
nl,
display(N, 0, L).
display(N, M, [H | T]) :-
writef('%3r', [H]),
M1 is M + 1,
display(N, M1, T).

View file

@ -0,0 +1,57 @@
:- initialization(main).
board_size(8).
in_board(X*Y) :- board_size(N), between(1,N,Y), between(1,N,X).
% express jump-graph in dynamic "move"-rules
make_graph :-
findall(_, (in_board(P), assert_moves(P)), _).
% where
assert_moves(P) :-
findall(_, (can_move(P,Q), asserta(move(P,Q))), _).
can_move(X*Y,Q) :-
( one(X,X1), two(Y,Y1) ; two(X,X1), one(Y,Y1) )
, Q = X1*Y1, in_board(Q)
. % where
one(M,N) :- succ(M,N) ; succ(N,M).
two(M,N) :- N is M + 2 ; N is M - 2.
hamiltonian(P,Pn) :-
board_size(N), Size is N * N
, hamiltonian(P,Size,[],Ps), enumerate(Size,Ps,Pn)
.
% where
enumerate(_, [] , [] ).
enumerate(N, [P|Ps], [N:P|Pn]) :- succ(M,N), enumerate(M,Ps,Pn).
hamiltonian(P,N,Ps,Res) :-
N =:= 1 -> Res = [P|Ps]
; warnsdorff(Ps,P,Q), succ(M,N)
, hamiltonian(Q,M,[P|Ps],Res)
.
% where
warnsdorff(Ps,P,Q) :-
moves(Ps,P,Qs), maplist(next_moves(Ps), Qs, Xs)
, keysort(Xs,Ys), member(_-Q,Ys)
.
next_moves(Ps,Q,L-Q) :- moves(Ps,Q,Rs), length(Rs,L).
moves(Ps,P,Qs) :-
findall(Q, (move(P,Q), \+ member(Q,Ps)), Qs).
show_path(Pn) :- findall(_, (in_board(P), show_cell(Pn,P)), _).
% where
show_cell(Pn,X*Y) :-
member(N:X*Y,Pn), format('%3.0d',[N]), board_size(X), nl.
main :- make_graph, hamiltonian(5*3,Pn), show_path(Pn), halt.