1
% SEND+MORE=MONEY
solve(VarList):-
    VarList=[D,E,M,N,O,R,S,Y],     % Οι μεταβλητές του προβλήματος
    Digits=[0,1,2,3,4,5,6,7,8,9],  % Οι τιμές των μεταβλητών (τα ψηφία)
    member(D,Digits),
    member(E,Digits),
    member(M,Digits),
    member(N,Digits),     % Ανάθεση τιμών στις μεταβλητές
    member(O,Digits),
    member(R,Digits),
    member(S,Digits),
    member(Y,Digits),
    M=0, S=0,           % Περιορισμοί
    E=D,
    M=D, M=E,
    N=D, N=E, N=M,
    O=D, O=E, O=M, O=N,
    R=D, R=E, R=M, R=N, R=O,
    S=D, S=E, S=M, S=N, S=O, S=R,
    Y=D, Y=E, Y=M, Y=N, Y=O, Y=R, Y=S,
    S*1000+E*100+N*10+D + M*1000+O*100+R*10+E =:= M*10000+O*1000+N*100+E*10+Y.

如果我减少变量 VarList 的数量。它提高了速度吗?

如果我S*1000+E*100+N*10+D + M*1000+O*100+R*10+E =:= M*10000+O*1000+N*100+E*10+Y

在检查之前它会提高速度吗?

4

2 回答 2

1

一种方法,我正在提出我的解决方案,以防有人正在研究这个问题。

:- use_module( library( clpfd)).

puzzle(X):-
    X=([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,
    
    S*1000 + E*100 + N*10 + D +
    M*1000 + O*100 + R*10 + E #=
    M*1000 + O*1000 + N*100 + E*10 + Y,
    
    S#\=0, M#\=0,
    all_different(Vars),
    labeling([],Vars).

?- puzzle(X).
X = ([1, 8, 0, 5]+[4, 2, 7, 8]=[4, 2, 0, 8, 3])
X = ([1, 8, 0, 5]+[6, 2, 7, 8]=[6, 2, 0, 8, 3])
X = ([1, 8, 0, 5]+[9, 2, 7, 8]=[9, 2, 0, 8, 3])
X = ([1, 8, 0, 6]+[3, 2, 7, 8]=[3, 2, 0, 8, 4])
X = ([1, 8, 0, 6]+[5, 2, 7, 8]=[5, 2, 0, 8, 4])
X = ([1, 8, 0, 6]+[9, 2, 7, 8]=[9, 2, 0, 8, 4])
X = ([2, 7, 0, 4]+[5, 3, 6, 7]=[5, 3, 0, 7, 1])....
于 2020-12-07T18:02:28.247 回答
0

不,如果你移动这条线

S*1000+E*100+N*10+D + M*1000+O*100+R*10+E =:= M*10000+O*1000+N*100+E*10+Y

你所说的“ Περιορισμοί”(“限制”,根据谷歌翻译)之上,它只会变得更慢,因为它会不必要地执行算术计算,这本来可以通过限制首先清除非法数字分配来避免。

你也有错误的方程式S = 0, M = 0, E = D, ...S =\= 0, M =\= 0, E =\= D, ...因为这些数字中的所有数字都必须是唯一的,并且数字中的第一个数字不能为零。

总体而言,您的代码速度可以提高,方法是减少可用值的域,每次选择一个数字值,使用select/3,而不是从同一个未受影响的域中进行所有Digits选择member/2。这将大大减少组合​​选择空间,并且通过构造避免不等式检查,选择的所有数字都将不同。标签的信息页面和问答条目应该有更多关于这种技术的讨论和/或示例(还有标签)。

于 2020-12-08T12:38:13.533 回答