/******************************************************************************
###############################################################################
#                                                                             #
#                                 NEUF + DEUX                                 #
#                                 ___________                                 #
#                                                                             #
#                            Version : 2020-04-03                             #
#                             Auteur : Denis NICOLAS                          #
#                            Licence : GNU GPL Version 3                      #
#                                                                             #
###############################################################################

"
  NEUF
+ DEUX
______
  ONZE
  
Chaque lettre représente toujours le même chiffre.
Il vous faut retrouver les chiffres correspondant aux lettres de sorte que le résultat de l'addition sous forme de chiffres ainsi formée soit également correct.
"

Chacune des 8 lettres doit être associée à un chiffre différent.

***

Ce programme Prolog permet de trouver toutes les solutions !
Il y en a 76.

******************************************************************************/

chiffre(C) :-
    member(C, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]).


/* Chaque retenue est 0 ou 1. */
retenue(R) :-
    member(R, [0, 1]).


/* Colonne des unités => retenue : R1. */
equation1(F, X, R1, E) :-
    F + X =:= 10 * R1 + E.


/* Colonne des dizaines => retenue : R2. */
equation2(R1, U, R2, Z) :-
    R1 + 2 * U =:= 10 * R2 + Z.


/* Colonne des centaines => retenue : R3. */
equation3(R2, E, R3, N) :-
    R2 + 2 * E =:= 10 * R3 + N.


/* Colonne des milliers => pas de retenue. */
equation4(R3, N, D, O) :-
    R3 + N + D =:= O.


/* Chercher une solution et l'afficher. */
systeme(N, E, U, F, D, X, O, Z, R1, R2, R3) :-
    chiffre(N),
    chiffre(E),
    chiffre(U),
    chiffre(F),
    chiffre(D),
    chiffre(X),
    chiffre(O),
    chiffre(Z),
    
    /*
    Chacune des 8 lettres doit être associée à un chiffre différent.
    Beaucoup plus élégant, mais sensiblement plus lent :
    is_set([N, E, U, F, D, X, O, Z])
    */
    N \== E,
    N \== U,
    N \== F,
    N \== D,
    N \== X,
    N \== O,
    N \== Z,
    
    E \== U,
    E \== F,
    E \== D,
    E \== X,
    E \== O,
    E \== Z,
    
    U \== F,
    U \== D,
    U \== X,
    U \== O,
    U \== Z,

    F \== D,
    F \== X,
    F \== O,
    F \== Z,
    
    D \== X,
    D \== O,
    D \== Z,

    X \== O,
    X \== Z,
    
    O \== Z,
    
    retenue(R1),
    retenue(R2),
    retenue(R3),
    
    equation1(F, X, R1, E),
    equation2(R1, U, R2, Z),
    equation3(R2, E, R3, N),
    equation4(R3, N, D, O),
    
    format('~w~w~w~w + ~w~w~w~w = ~w~w~w~w~n', [N, E, U, F, D, E, U, X, O, N, Z, E]).


/* Afficher toutes les solutions et le nombre de solutions. */
afficher_tout :-
    findall((N, E, U, F, D, X, O, Z), systeme(N, E, U, F, D, X, O, Z, _, _, _), Bag),
    length(Bag, L),
    format('~n~w solutions.~n', [L]).


:-
    afficher_tout,
    halt.
