Нужна помощь с похожим кодом More Money для Пролога

Каждая буква в загадке однозначно представляет одну из 10 цифр в 0, 1, …, 9. Никакие две буквы не представляют одну и ту же цифру. Для каждого слова ниже в загадке первая буква не равна 0.

Пример: SHINE - THAN == ВЯЗАНИЕ

Все, что у меня есть для кода, это...

:- 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
                      )
             )
     ).

Я как бы застрял на этой части. Поэтому, когда я запустил код без функции compareLists(List), результат дал мне "Нет". Поэтому, когда я добавил функцию CompareLists (List), ответ все равно дал мне "Нет". Мне было интересно, если "Нет" является правильным ответом или я написал что-то неправильно в моем коде? Любая помощь приветствуется. Спасибо!

Спасибо!

1 ответ

Решение

Почти все минусы в вашей модели (кроме одного) должны быть плюсами. Даже если в "SHINE - THAN" есть знак минус, SHINE остается (10000*S + 1000*H + 100*I + 10*N + E) - это просто математика.

Также нет необходимости заново изобретать стандартные предикаты alldifferent (названный diff_list в вашем коде) и labeling (названный shallow_backtrack в вашем коде). Не только ваша программа содержит много ненужного кода, но и стандартные предикаты будут гораздо более эффективными во многих ситуациях, а также более гибкими.

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

:- 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).
Другие вопросы по тегам