Search code examples
prologcryptarithmetic-puzzleeclipse-clp

Need assistance with similar More Money code for Prolog


Every letter below in the puzzle uniquely represent one of the 10 digits in 0, 1, …, 9. No two letters represent the same digit. For each word below in the puzzle, the first letter is not 0.

Ex: SHINE - THAN == KNIT

All I've got for the code is this...

:- lib(ic).

exampleOne(List) :-
    List = [S, H, I, N, E, T, A, K],
    List :: 0..9,
    diff_list(List),
    (10000*S - 1000*H - 100*I - 10*N - E)
    - (1000*T - 100*H - 10*A - N)
    $= (1000*K - 100*N - 10*I - T),
    S $\= 0, T $\= 0, K $\= 0,
    shallow_backtrack(List).

shallow_backtrack(List) :-
    ( foreach(Var, List) do once(indomain(Var)) ).

diff_list(List) :-
    ( fromto(List, [X|Tail], Tail, []) do
          ( fromto(Y, Tail, param(X) do
              X $\= Y
          )
    ).

compareLists(List) :-
    length(List, N),
    ( foreach(Input1, List), count(I, 1, N), param(N, List)
        do
             ( foreach(Input2, List), count(J, 1, N), param(List, Input1, I, N)
                  do
                      ( ( I $\= J, Input1 $\= Input2 )
                            -> true;
                            fail
                      )
             )
     ).

I'm kinda stuck on this part. So when I ran the code without the compareLists(List) function, the result gives me "No". So when I added the compareLists(List) function, the answer still gives me "No". I was wondering if "No" is the right answer or did I write something wrong in my code? Any help is appreciated. Thanks!

Thanks!


Solution

  • Almost all minuses in your model (except one) must be pluses. Even if there is a minus sign in 'SHINE - THAN', SHINE is still (10000*S + 1000*H + 100*I + 10*N + E) - it's just simple math.

    Also no need to reinvent standard predicates alldifferent (named diff_list in your code) and labeling (named shallow_backtrack in your code). Not only your program has a lot of unneeded code, but also standard predicates will be much more efficient in many situations and also more flexible.

    Here is complete corrected program that uses standard ic library predicates:

    :- lib(ic).
    
    exampleOne(List) :-
        List = [S, H, I, N, E, T, A, K],
        List :: 0..9,
        alldifferent(List),
        (10000*S + 1000*H + 100*I + 10*N + E)
        - (1000*T + 100*H + 10*A + N)
        $= (1000*K + 100*N + 10*I + T),
        S $\= 0, T $\= 0, K $\= 0,
        labeling(List).