Криптарифметическая операция

Я пытался написать код Пролога для "ОТПРАВИТЬ ДЕНЬГИ РЕЖИМА". Пока что я получил следующее:

:- use_module(library(clpfd)).

puzzle([S,E,N,D] + [M,O,R,E] = [M,O,N,E,Y]) :- 
   Vars = [S,E,N,D,M,O,R,Y], 
   Vars ins 0..9, 
   all_different(Vars), 
   S*1000 + E*100 + N*10 + D + M*1000 + O*100 + R*10 + E 
       #= M*10000 + O*1000 + N*100 + E*10 + Y, 
   M #\= 0, 
   S #\= 0,
   label([S,E,N,D,M,O,R,Y]),
   format('~s ~w ~s ~w ~s ~w ~s ~w ~s ~s ~s ~w ~s ~w ~s ~w ~s ~w ~s ~s ~s ~w ~s ~w ~s ~w ~s ~w ~s ~w ~s ~s',
        [ "[", S, ",", E, ",", N, ",", D, "]",
         "+", "[", M, ",", O, ",", R, ",", E, "]",
         "=", "[", M, ",", O, ",", N,  ",", E, ",", Y, "]", ";" ]).

Вывод следующий:

?- puzzle([S,E,N,D] + [M,O,R,E] = [M,O,N,E,Y]).

[ 9 , 5 , 6 , 7 ] + [ 1 , 0 , 8 , 5 ] = [ 1 , 0 , 6 , 5 , 2 ] ;
S = 9,
E = 5,
N = 6,
D = 7,
M = 1,
O = 0,
R = 8,
Y = 2.

Но я хочу напечатать список в конце, а не в начале, как я могу это сделать?

Вывод, который мне нужно получить:

?- puzzle([S,E,N,D] + [M,O,R,E] = [M,O,N,E,Y]).
S = 9,
E = 5,
N = 6,
D = 7,
M = 1,
O = 0,
R = 8,
Y = 2.
[ 9 , 5 , 6 , 7 ] + [ 1 , 0 , 8 , 5 ] = [ 1 , 0 , 6 , 5 , 2 ] ;

Спасибо.

1 ответ

Решение

Если вы хотите, чтобы форматированный вывод отличался от ответов, которые предоставляет Пролог, я бы предложил четко отделить фактическое отношение от вывода. Итак, давайте удалим последнюю цель из вашей загадки предиката /1:

puzzle([S,E,N,D] + [M,O,R,E] = [M,O,N,E,Y]) :- 
   Vars = [S,E,N,D,M,O,R,Y], 
   Vars ins 0..9, 
   all_different(Vars), 
   S*1000 + E*100 + N*10 + D + M*1000 + O*100 + R*10 + E 
       #= M*10000 + O*1000 + N*100 + E*10 + Y, 
   M #\= 0, 
   S #\= 0,
   label([S,E,N,D,M,O,R,Y]).

Напишите предикат, который имеет дело с выводом. Следуя вашему примеру желаемого вывода, это может быть что-то вроде вывода запроса, за которым следуют подстановки переменных, по одной на строку, и, наконец, уравнение ввода с буквами, замененными числами, которые решают головоломку (это как раз последняя цель из вашей версии головоломка /1):

output([S,E,N,D] + [M,O,R,E] = [M,O,N,E,Y]) :-
   format('?- puzzle([S,E,N,D] + [M,O,R,E] = [M,O,N,E,Y]).~n'),
   format('S = ~d,~nE = ~d,~nN = ~d,~nD = ~d,~nM = ~d,~nO = ~d,~nR = ~d,~nY = ~d.~n',[S,E,N,D,M,O,R,Y]),
   format('~s ~w ~s ~w ~s ~w ~s ~w ~s ~s ~s ~w ~s ~w ~s ~w ~s ~w ~s ~s ~s ~w ~s ~w ~s ~w ~s ~w ~s ~w ~s ~s',[ "[", S, ",", E, ",", N, ",", D, "]",  "+", "[", M, ",", O, ",", R, ",", E, "]", "=", "[", M, ",", O, ",", N,  ",", E, ",", Y, "]", ";" ]).

И тогда у вас есть вызывающий предикат без аргументов, поэтому генерируется только желаемый результат:

puzzleout :-
   puzzle(X),
   output(X).

Таким образом, у вас есть предикат, который решает головоломку и больше ничего не делает:

?- puzzle([S,E,N,D] + [M,O,R,E] = [M,O,N,E,Y]).
S = 9,
E = 5,
N = 6,
D = 7,
M = 1,
O = 0,
R = 8,
Y = 2 ;
false.

И у вас также есть предикат, который генерирует желаемый результат:

?- puzzleout.
?- puzzle([S,E,N,D] + [M,O,R,E] = [M,O,N,E,Y]).
S = 9,
E = 5,
N = 6,
D = 7,
M = 1,
O = 0,
R = 8,
Y = 2.
[ 9 , 5 , 6 , 7 ] + [ 1 , 0 , 8 , 5 ] = [ 1 , 0 , 6 , 5 , 2 ] ;
true ;
false.

Обратите внимание, что вторая строка не является введенным вами запросом, а генерируется как вывод первой целью output/1.

Другие вопросы по тегам