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 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137
|
%------------------- ICI LE LISTING A COPIER COLLER
%problème de la traversée du professeur Layton et l'étrange village sur Nintendo DS
%le but du problème est d'amener 3 poussins et 3 loups d'une rive A à une rive B
%on ne peut déplacer que 2 animaux à la fois
%les loups ne doivent pas être supérieurs aux poussins en nombre sur aucune rive
%on ne peut déplacer la barque sans animaux dedans
%une solution existe en 11 coups
%ce programme en PROLOG a été écrit en SWI-PROLOG
%traverse(rive(LOUPS1, POUSSINS1), rive(LOUPS2, POUSSINS2), true, PMOV)
%=>rive(LOUPS1, POUSSINS1) : la rive A avec son nombre de poussins et son nombre de loups
%=>rive(LOUPS2, POUSSINS2) : la rive B avec son nombre de poussins et son nombre de loups
%=>true : on déplace les animaux de la rive A à la rive B, false pour l'inverse
%=>PMOV : le nombre de coups restant, décrémenté jusqu'à 0
%ATTENTION si une solution est générée, elle se lit en commençant par la fin et en remontant
%jusqu'au début
debug(_,_,_,_).
%debug(rive(LOUPS1, POUSSINS1), rive(LOUPS2, POUSSINS2), PMOV, ACT) :-
% write(PMOV), write(':'),write(ACT),write('#('), write(LOUPS1), write(','), write(POUSSINS1), write(')-('),
% write(LOUPS2), write(','), write(POUSSINS2), writeln(')').
%les loups sur l'une des rive données peuvent ils prendrent des poussins ?
%=>oui si ils sont plus nombreux et qu'il y a au moins un poussin
prise(rive(LOUPS, POUSSINS)) :-
POUSSINS > 0,
LOUPS > POUSSINS.
%pour chaque clause traverse on test si aucune prise n'est possible et si on a pas atteint
%le nombre maximal de coups : ce prédicat est présent dans chaque clause du prédicat "traverse"
constraint(rive(LOUPS1, POUSSINS1), rive(LOUPS2, POUSSINS2), PMOV) :-
not(prise(rive(LOUPS1, POUSSINS1))),
not(prise(rive(LOUPS2, POUSSINS2))),
PMOV >= 0.
%clause de réussite : tous les animaux sont passés de la rive A à la rive B
traverse(rive(0, 0), rive(3, 3), _, _).
traverse(rive(LOUPS1, POUSSINS1), rive(LOUPS2, POUSSINS2), true, PMOV) :-
constraint(rive(LOUPS1, POUSSINS1), rive(LOUPS2, POUSSINS2), PMOV),
LOUPS1 >= 1, %traversée de 1 loup de rive A vers B
ZLOUPS1 is LOUPS1 - 1, ZLOUPS2 is LOUPS2 + 1,
ZMOV is PMOV - 1,
debug(rive(LOUPS1, POUSSINS1), rive(LOUPS2, POUSSINS2), PMOV, '1L->'),
traverse(rive(ZLOUPS1, POUSSINS1), rive(ZLOUPS2, POUSSINS2), false, ZMOV),
write(PMOV), writeln(':1L->').
traverse(rive(LOUPS1, POUSSINS1), rive(LOUPS2, POUSSINS2), true, PMOV) :-
constraint(rive(LOUPS1, POUSSINS1), rive(LOUPS2, POUSSINS2), PMOV),
LOUPS1 >= 2, %traversée de 2 loups de rive A vers B
ZLOUPS1 is LOUPS1 - 2, ZLOUPS2 is LOUPS2 + 2,
ZMOV is PMOV - 1,
debug(rive(LOUPS1, POUSSINS1), rive(LOUPS2, POUSSINS2), PMOV, '2L->'),
traverse(rive(ZLOUPS1, POUSSINS1), rive(ZLOUPS2, POUSSINS2), false, ZMOV),
write(PMOV), writeln(':2L->').
traverse(rive(LOUPS1, POUSSINS1), rive(LOUPS2, POUSSINS2), true, PMOV) :-
constraint(rive(LOUPS1, POUSSINS1), rive(LOUPS2, POUSSINS2), PMOV),
POUSSINS1 >= 1, %traversée de 1 poussin de rive A vers B
ZPOUSSINS1 is POUSSINS1 - 1, ZPOUSSINS2 is POUSSINS2 + 1,
ZMOV is PMOV - 1,
debug(rive(LOUPS1, POUSSINS1), rive(LOUPS2, POUSSINS2), PMOV, '1P->'),
traverse(rive(LOUPS1, ZPOUSSINS1), rive(LOUPS2, ZPOUSSINS2), false, ZMOV),
write(PMOV), writeln(':1P->').
traverse(rive(LOUPS1, POUSSINS1), rive(LOUPS2, POUSSINS2), true, PMOV) :-
constraint(rive(LOUPS1, POUSSINS1), rive(LOUPS2, POUSSINS2), PMOV),
POUSSINS1 >= 2, %traversée de 2 poussins de rive A vers B
ZPOUSSINS1 is POUSSINS1 - 2, ZPOUSSINS2 is POUSSINS2 + 2,
ZMOV is PMOV - 1,
debug(rive(LOUPS1, POUSSINS1), rive(LOUPS2, POUSSINS2), PMOV, '2P->'),
traverse(rive(LOUPS1, ZPOUSSINS1), rive(LOUPS2, ZPOUSSINS2), false, ZMOV),
write(PMOV), writeln(':2P->').
traverse(rive(LOUPS1, POUSSINS1), rive(LOUPS2, POUSSINS2), true, PMOV) :-
constraint(rive(LOUPS1, POUSSINS1), rive(LOUPS2, POUSSINS2), PMOV),
POUSSINS1 >= 1, %traversée de 1 poussin et 1 loup de rive A vers B
LOUPS1 >= 1,
ZPOUSSINS1 is POUSSINS1 - 1, ZPOUSSINS2 is POUSSINS2 + 1,
ZLOUPS1 is LOUPS1 - 1, ZLOUPS2 is LOUPS2 + 1,
ZMOV is PMOV - 1,
debug(rive(LOUPS1, POUSSINS1), rive(LOUPS2, POUSSINS2), PMOV, '1L1P->'),
traverse(rive(ZLOUPS1, ZPOUSSINS1), rive(ZLOUPS2, ZPOUSSINS2), false, ZMOV),
write(PMOV), writeln(':1L1P->').
%les clauses qui suivent sont pour la traversée de la rive B vers la rive A
traverse(rive(LOUPS1, POUSSINS1), rive(LOUPS2, POUSSINS2), false, PMOV) :-
constraint(rive(LOUPS1, POUSSINS1), rive(LOUPS2, POUSSINS2), PMOV),
LOUPS2 >= 1,
ZLOUPS1 is LOUPS1 + 1, ZLOUPS2 is LOUPS2 - 1,
ZMOV is PMOV - 1,
debug(rive(LOUPS1, POUSSINS1), rive(LOUPS2, POUSSINS2), PMOV, '<-1L'),
traverse(rive(ZLOUPS1, POUSSINS1), rive(ZLOUPS2, POUSSINS2), true, ZMOV),
write(PMOV), writeln(':<-1L').
traverse(rive(LOUPS1, POUSSINS1), rive(LOUPS2, POUSSINS2), false, PMOV) :-
constraint(rive(LOUPS1, POUSSINS1), rive(LOUPS2, POUSSINS2), PMOV),
LOUPS2 >= 2,
ZLOUPS1 is LOUPS1 + 2, ZLOUPS2 is LOUPS2 - 2,
ZMOV is PMOV - 1,
debug(rive(LOUPS1, POUSSINS1), rive(LOUPS2, POUSSINS2), PMOV, '<-2L'),
traverse(rive(ZLOUPS1, POUSSINS1), rive(ZLOUPS2, POUSSINS2), true, ZMOV),
write(PMOV), writeln(':<-2L').
traverse(rive(LOUPS1, POUSSINS1), rive(LOUPS2, POUSSINS2), false, PMOV) :-
constraint(rive(LOUPS1, POUSSINS1), rive(LOUPS2, POUSSINS2), PMOV),
POUSSINS2 >= 1,
ZPOUSSINS1 is POUSSINS1 + 1, ZPOUSSINS2 is POUSSINS1 - 1,
ZMOV is PMOV - 1,
debug(rive(LOUPS1, POUSSINS1), rive(LOUPS2, POUSSINS2), PMOV, '<-1P'),
traverse(rive(LOUPS1, ZPOUSSINS1), rive(LOUPS2, ZPOUSSINS2), true, ZMOV),
write(PMOV), writeln(':<-1P').
traverse(rive(LOUPS1, POUSSINS1), rive(LOUPS2, POUSSINS2), false, PMOV) :-
constraint(rive(LOUPS1, POUSSINS1), rive(LOUPS2, POUSSINS2), PMOV),
POUSSINS2 >= 2,
ZPOUSSINS1 is POUSSINS1 + 2, ZPOUSSINS2 is POUSSINS1 - 2,
ZMOV is PMOV - 1,
debug(rive(LOUPS1, POUSSINS1), rive(LOUPS2, POUSSINS2), PMOV, '<-2P'),
traverse(rive(LOUPS1, ZPOUSSINS1), rive(LOUPS2, ZPOUSSINS2), true, ZMOV),
write(PMOV), writeln(':<-2P').
traverse(rive(LOUPS1, POUSSINS1), rive(LOUPS2, POUSSINS2), false, PMOV) :-
constraint(rive(LOUPS1, POUSSINS1), rive(LOUPS2, POUSSINS2), PMOV),
POUSSINS2 >= 1,
LOUPS2 >= 1,
ZLOUPS1 is LOUPS1 + 1, ZLOUPS2 is LOUPS2 - 1,
ZPOUSSINS1 is POUSSINS1 + 1, ZPOUSSINS2 is POUSSINS1 - 1,
ZMOV is PMOV - 1,
debug(rive(LOUPS1, POUSSINS1), rive(LOUPS2, POUSSINS2), PMOV, '<-1L1P'),
traverse(rive(ZLOUPS1, ZPOUSSINS1), rive(ZLOUPS2, ZPOUSSINS2), true, ZMOV),
write(PMOV), writeln(':<-1L1P').
%ici c'est le but en 12 coups max :
%?- traverse(rive(3, 3), rive(0, 0), true, 12). |
Partager