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
| :- use_module(library('clpfd.pl')).
test(N) :-
Number is N * (N+1) / 2,
length(Vars, Number),
Vars ins 1..Number,
all_different(Vars),
% initialisation des règles de construction de la pyramide
init_vars(Vars, 1, N),
label(Vars),
% ecriture de la pyramide
write_vars(1, N, Vars),
nl, nl.
% initialisation ligne par ligne
init_vars(_L, N, N).
init_vars(L, N, Max) :-
init_line(L, N),
N1 is N + 1,
init_vars(L, N1, Max).
% on a besoin du numéro de ligne
% et de la liste des variables
init_line(L, N) :-
% Calcul des indices dans la liste des variables
Min is (N - 1) * N/2 + 1,
Max is Min + N - 1,
init_val(L, N, Min, Max).
% initalisation de chaque élément de la liste
init_val(L, N, M, M) :-
!,
% un nombre de la pyramide est la valeur absolue
% des la différences des deux nombres qui sont en dessous
% de lui
nth1(M, L, E1),
I1 is M + N,
nth1(I1, L, E2),
I2 is I1 + 1,
nth1(I2, L, E3),
% affectation de la contrainte à l'élément
affecte_val(E1,E2,E3).
init_val(L, N, M1, M) :-
!,
nth1(M1, L, E1),
I1 is M1 + N,
nth1(I1, L, E2),
I2 is I1 + 1,
nth1(I2, L, E3),
affecte_val(E1,E2,E3),
M2 is M1 + 1,
init_val(L, N, M2, M).
% il faut distinguer à cause des contraintes
% de la programmation par contraintes !!
% deux cas
affecte_val(E1,E2,E3) :-
E2 #> E3,
E1 #= E2 - E3.
affecte_val(E1,E2,E3) :-
E2 #< E3,
E1 #= E3 - E2.
% ecriture de la pyramide
write_vars(_, _, []).
% ici on écrit N nombres
% On décale d'abord de la place de Max - N + 1 nombres
write_vars(N, Max, V) :-
K is Max - N,
forall(between(1, K, _), write(' ')),
write_nombre(N, V, V1),
N1 is N+1,
write_vars(N1, Max, V1).
write_nombre(0, L, L) :-
!,
nl.
% l'affichage est prévu pour des nombres inférieurs à 100
write_nombre(N, [H|T], L) :-
( H < 10 -> write(' '); true), write(H), write(' '),
N1 is N - 1,
write_nombre(N1, T, L). |
Partager