tele7jeux.pl : test de prolog / P. TRAU


/* je veux les solutions de UNE+UNE=DEUX */

/*
 * pour commencer, rappel sur les opérateurs arithmétiques :
 * attention :  bien faire la différence entre is, = et =:=
 * - is calcule la valeur à droite (toujours liée) et instancie le résultat à la variable (libre)
 * à gauche,  ou la compare à la val liée de gauche. par ex X is 10+15 met 25 dans X, ou dit True
 * si X vaut 25 (parce que avant on a dit X is 30-5 ou même X=25)
 * - = recopie l'équation avec les variables instanciées : Y=10,X=Y+15,write(X). affiche 10+15
 * mais on pourra toujours tester X par =:= (ou même is, si il est à droite du is).
 * Au moins un des arguments doit être lié.
 * - =:= évalue à droite et à gauche et regarde si les résultats sont égaux (les deux arguments doivent être liés)
 * les opérateurs de comparaison (qui évaluent à droite et à gauche) sont  : 
 *  =:=  =\=  <  >  =<  >= ,les opérateurs arithmétiques : + - * / mod ** , sin,cos,log .... (voir help(3-22).)  */


chiffre(X):-between(0,9,X). /* between prédicat prédéfini */

/* solution de base 
chiffre(0).
chiffre(1).
chiffre(2).
chiffre(3).
chiffre(4).
chiffre(5).
chiffre(6).
chiffre(7).
chiffre(8).
chiffre(9).
*/

chiffres([T|[]]):-chiffre(T).
chiffres([T|Q]):-chiffre(T),chiffres(Q).

membre(X,[X|_]).
membre(X,[_|Q]):-membre(X,Q).

tous_differents([]).
tous_differents([T|Q]):- not(membre(T,Q)),tous_differents(Q).

/* permutation(ListeInitiale,LesMemesDansUnAutreOrdre).
 * si le deuxière arg est libre, donne toutes les permutations possibles.
 * Attention la listeinitale est aussi une des solutions */
permutation(ListeInitiale,[T|Result]):-select(ListeInitiale,T,Tmp),permutation(Tmp,Result).
permutation([],[]).

/* attention :  bien faire la différence entre is, = et =:= */
eval(Dixmille,Mille,Cent,Dix,Un,Result):-Result is 10000*Dixmille+1000*Mille+100*Cent+10*Dix+Un.
/* grace à la liste, le nb d'arguments devient variable */
evalue(ListeChiffres,Resultat) :-
	append(TousSaufDernier,[Dernier],ListeChiffres),
	evalue(TousSaufDernier,X),
	Resultat is Dernier + 10*X.
evalue([X],X).

/* UNE+UNE=DEUX */
une :- 
	chiffres([U,N,E,D,X]), % attention 10^5 solutions !!!
	tous_differents([U,N,E,D,X]),
        U=\=0,D=\=0,  % =\= signifie différent
/*les 3 lignes ci-dessous remplacent la 4ème */
        evalue([U,N,E],Une),   % ou eval(0,0,U,N,E)
        evalue([D,E,U,X],Deux),
        Deux =:= Une+Une,
/*la ligne ci-dessous marche aussi, avec le =:= (et va un peu plus vite)
 *	200*U+20*N+2*E=:=1000*D+100*E+10*U+X, %remarquez que =:= évalue alors que = concatène les caractères */
        write(U),write(N),write(E),write(' + '),write(U),write(N),write(E),
		write(' = '),write(D),write(E),write(U),write(X),nl,
        fail. /*pour avoir toutes les solutions*/

/* FORTY+TEN+TEN=SIXTY le calcul m'a l'air bien long (environ 10 mn). solution unique : 29786 + 850 + 850 = 31486 */
forty :- 
/* le calcul ci-dessous est trop long, j'ai 10 variables donc je peux utiliser les permutations de 10 chiffres 
   pour 6 chiffres : 15 s, 7=150"=2.5' 8=25' 9=250'=4h 10=40h (je n'ai testé que le temps pour 6 chiffres, le reste est supposition) 
	chiffres([F,O,R,T,Y,E,N,S,I,X]), %attention 10^10 solutions ! 
	tous_differents([F,O,R,T,Y,E,N,S,I,X]),
*/
        permutation([0,1,2,3,4,5,6,7,8,9],[F,O,R,T,Y,E,N,S,I,X]),
        F=\=0,T=\=0,S=\=0, 
/* les 3 lignes ci-dessous ne déconnent plus */
	evalue([F,O,R,T,Y],Forty),
 	evalue([T,E,N],Ten),
        evalue([S,I,X,T,Y],Sixty),
        Forty+Ten+Ten =:= Sixty,
        write(Forty),write(' + '),write(Ten),write(' + '),write(Ten),
		write(' = '),write(Sixty),nl,
        fail. /*pour avoir toutes les solutions*/



Patrick TRAU, ULP - IPST janvier 2002

retour au cours Prolog    retour