/******************************************************************************
###############################################################################
#                                                                             #
#                                 FOUR + FIVE                                 #
#                                 ___________                                 #
#                                                                             #
#                            Version: 2020-04-03                              #
#                             Author: Denis NICOLAS                           #
#                            License: GNU GPL Version 3                       #
#                                                                             #
###############################################################################

  FOUR
+ FIVE
______
  NINE

Each letter always represents the same digit.
You have to find the digits corresponding to the letters so that the result of the addition you get after substituting the letters with digits is also correct.

Each of the 8 letters must be associated with a different digit.

***

This Prolog program finds all the solutions!
There are 72 solutions.

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

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


/* Each carry is 0 or 1. */
carry(C) :-
    member(C, [0, 1]).


/* Units column => carry: C1. */
equation1(R, E, C1) :-
    R + E =:= 10 * C1 + E.


/* Tens column => carry: C2. */
equation2(C1, U, V, C2, N) :-
    C1 + U + V =:= 10 * C2 + N.


/* Hundreds column => carry: C3. */
equation3(C2, O, I, C3) :-
    C2 + O + I =:= 10 * C3 + I.


/* Thousands column => no carry. */
equation4(C3, F, N) :-
    C3 + 2 * F =:= N.


/* Find a solution and display it. */
equations(F, O, U, R, I, V, E, N, C1, C2, C3) :-
    digit(F),
    digit(O),
    digit(U),
    digit(R),
    digit(I),
    digit(V),
    digit(E),
    digit(N),
    
    /*
    Each of the 8 letters must be associated with a different digit.
    Much more elegant, but quite slower:
    is_set([F, O, U, R, I, V, E, N])
    */
    F \== O,
    F \== U,
    F \== R,
    F \== I,
    F \== V,
    F \== E,
    F \== N,
    
    O \== U,
    O \== R,
    O \== I,
    O \== V,
    O \== E,
    O \== N,
    
    U \== R,
    U \== I,
    U \== V,
    U \== E,
    U \== N,

    R \== I,
    R \== V,
    R \== E,
    R \== N,
    
    I \== V,
    I \== E,
    I \== N,

    V \== E,
    V \== N,
    
    E \== N,
    
    carry(C1),
    carry(C2),
    carry(C3),
    
    equation1(R, E, C1),
    equation2(C1, U, V, C2, N),
    equation3(C2, O, I, C3),
    equation4(C3, F, N),
    
    format('~w~w~w~w + ~w~w~w~w = ~w~w~w~w~n', [F, O, U, R, F, I, V, E, N, I, N, E]).


/* Display all the solutions and the number of solutions. */
display_all :-
    findall((F, O, U, R, I, V, E, N), equations(F, O, U, R, I, V, E, N, _, _, _), Bag),
    length(Bag, L),
    format('~n~w solutions.~n', [L]).


:-
    display_all,
    halt.
