Search code examples
prologcryptarithmetic-puzzle

Prolog implementation of SEND + MORE = MONEY isn't finding a result


I'm getting started with Prolog, and decided to try the famous SEND+MORE=MONEY puzzle, as it seemed fairly straightforward. However, my implementation does find a result.

Can anyone see what I did wrong?

smm([S, E, N, D, M, O, R, Y]) :-
  maplist(between(0, 9), [S, E, N, D, M, O, R, Y]),
  Line1 is           S*1000 + E*100 + N*10 + D,
  Line2 is           M*1000 + O*100 + R*10 + E,
  Sum   is M*10000 + O*1000 + N*100 + E*10 + Y,
  Sum = Line1 + Line2.

I'm not sure this is even the best way to approach this puzzle, so please feel free to make any (constructive!) comments on my code.

Update: Just in case anyone comes here looking for a solution to the puzzle, the code above wouldn't have worked anyway, as I forgot two important constraints, that M should not be zero, and that no two variables should be the same digit.

My amended code that works is as follows, but note that it slow. It took about 84s to solve on my machine, as compared to the code posted below by brebs, which solved it faster than I could see!

smm([S, E, N, D, M, O, R, Y]) :-
  maplist(between(0, 9), [S, E, N, D, M, O, R, Y]),
  M =\= 0,
  unique([S, E, N, D, M, O, R, Y]),
  Line1 is           S*1000 + E*100 + N*10 + D,
  Line2 is           M*1000 + O*100 + R*10 + E,
  Sum   is M*10000 + O*1000 + N*100 + E*10 + Y,
  Sum   is Line1 + Line2.

unique([]).
unique([H|T]) :- not(memberchk(H, T)), unique(T).

Solution

  • Just as you use is to compute the arithmetic expressions for Line1, Line2 and Sum, you need to use it for Line1 + Line2.