【问题标题】:Cryptarithmetic Multiplication Prolog密码乘法序言
【发布时间】:2014-05-16 13:54:04
【问题描述】:

我掌握了密码算术和加法的概念,但我不知道如何解决乘法密码算术问题。它只是 TWO*SIX=TWELVE 或类似的东西,没有给出乘法问题的中间附加部分。我在网上找不到任何东西,我已经发现了一些问题的限制,但没有什么可以让我找到一些答案。不知道在哪里问这个,并认为这是最好的地方。

我想知道如何解决一个乘法密码算术问题。

我已经得出结论了:

         T  W  O
*        S  I  X
_________________
T  W  E  L  V  E


T \= 0 which also means S \= 0
T is 1-6
E is (O*X) mod 10
O or X cannot be 0 or 1 since E has to be different and 0 or 1 gives the same value 
as either O or X.

编辑:我使用的是生成和测试方法

solve(T,W,O,S,I,X,E,L,V) :-
        X = [T,W,O,S,I,X,E,L,V],
        Digits = [0,1,2,3,4,5,6,7,8,9],
        assign_digits(X, Digits),
        T > 0, 
        S > 0,
        100*T + 10*W + O * 100*S + 10*I + X =:=
        100000*T + 10000*W + 1000*E + 100*L + 10*V + E,
        write(X).

select(X, [X|R], R).
select(X, [Y|Xs], [Y|Ys]):- select(X, Xs, Ys).

assign_digits([], _List).
assign_digits([D|Ds], List):-
        select(D, List, NewList),
        assign_digits(Ds, NewList).

【问题讨论】:

  • 明确说明您的问题。还要检查这是否不是您要查找的内容:stackoverflow.com/questions/23575795/…
  • 我把它放在那里,但我只是想知道如何至少在纸上解决问题。我不知道该怎么做,加法问题很容易。您发布的那个链接是一个附加问题,我理解这些。

标签: math prolog cryptarithmetic-puzzle


【解决方案1】:

与约束逻辑编程无关紧要。比如在ECLiPSe Prolog:

:- lib(ic).
puzzle(Vars) :-
    [T,W,O,S,I,X,E,L,V] = Vars,
    Vars :: 0..9,
    alldifferent(Vars),
    T #> 0, S #> 0,
    (100*T + 10*W + O) * (100*S + 10*I + X) #= 
      100000*T + 10000*W + 1000*E + 100*L + 10*V + E,
    labeling(Vars).

第一个解决方案:

[eclipse]: puzzle([T,W,O,S,I,X,E,L,V]).
T = 1
W = 6
O = 5
S = 9
I = 7
X = 2
E = 0
L = 3
V = 8
Yes (0.01s cpu, solution 1, maybe more) ? 

有 3 种不同的解决方案:

[eclipse]: puzzle([T,W,O,S,I,X,E,L,V]), writeln([T,W,O,S,I,X,E,L,V]), fail.
[1, 6, 5, 9, 7, 2, 0, 3, 8]
[2, 1, 8, 9, 6, 5, 0, 3, 7]
[3, 4, 5, 9, 8, 6, 0, 1, 7]
No (0.02s cpu)

更新 - 翻译成 SWI Prolog:

:- use_module(library(clpfd)).
puzzle(Vars) :-
    [T,W,O,S,I,X,E,L,V] = Vars,
    Vars ins 0..9,
    all_different(Vars),
    T #> 0, S #> 0,
    (100*T + 10*W + O) * (100*S + 10*I + X) #= 
      100000*T + 10000*W + 1000*E + 100*L + 10*V + E,
    label(Vars).

【讨论】:

  • 对eclipse prolog不太熟悉,我在swi prolog中做。你能解释一下labeling(Vars).all different(Vars).lib(ic)是什么吗?
  • @user2318083 我已将翻译添加到 SWI-Prolog。查看我的答案已更新。请参阅 clpfd 文档swi-prolog.org/pldoc/man?section=clpfd 了解更多信息。
  • 感谢您的帮助。我通过生成和测试以不同的方式接近它,我用我的代码对其进行了编辑,但它总是返回 false。我不知道为什么,如果您可以在那里查看我的代码,是否有可能?
  • @user2318083 您的代码有两个易于修复的问题。第一个问题,在X = [T,W,O,S,I,X,E,L,V], 中,您选择名称X 作为所有变量的列表,但您已经有一个名称为X 的变量!第二个问题是100*T + 10*W + O * 100*S + 10*I + X 中缺少括号。修复这些错误后,您的代码可以正常工作。
【解决方案2】:

更通用且无 CLP 的解决方案:

number_to_digits(Number,List) :-
        length(List,Len),
        ntb(0,Len,Number,List).

ntb(N,_,N,[]).
ntb(C,E,N,[D|L]) :-
        NE is E-1,
        V is C + D*10^NE,
        ntb(V,NE,N,L).

crypto(In1, In2, Out) :-
    term_variables([In1, In2, Out], Vars),
    permutation([0,1,2,3,4,5,6,7,8,9], Perm),
    append(_, Vars, Perm),
        number_to_digits(N1, In1),
        number_to_digits(N2, In2),
        number_to_digits(N3, Out),
        N3 is N1 * N2.

这是非常低效的,这个问题应该像@Sergey 那样使用 CLP 来解决,但也许有人会对没有 CLP 的可能解决方案感兴趣。

输入输出:

?- crypto([T,W,O], [S,I,X], [T,W,E,L,V,E]).
T = 0,
W = 5,
O = 7,
S = 9,
I = 6,
X = 2,
E = 4,
L = 8,
V = 3;
(...)

(57 * 962 = 54834)。

【讨论】:

    猜你喜欢
    • 2022-10-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多