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*/