% 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.
如果我减少varriables VarList的数量。它会提高速度吗?
如果我S*1000+E*100+N*10+D + M*1000+O*100+R*10+E =:= M*10000+O*1000+N*100+E*10+Y
在检查之前它会提高速度吗?
答案 0 :(得分:1)
一种clpfd方法,如果有人正在研究此问题,我会提出解决方案。
:- 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])....
答案 1 :(得分:0)
否,如果您移动直线
S*1000+E*100+N*10+D + M*1000+O*100+R*10+E =:= M*10000+O*1000+N*100+E*10+Y
上方,即您所说的“ Περιορισμοί
”(根据Google翻译,“限制”),只会变慢,因为它会不必要地执行本可以避免的算术计算并有限制,首先要清除掉非法数字分配。
当本来应该S = 0, M = 0, E = D, ...
时,您也会有错误的方程S =\= 0, M =\= 0, E =\= D, ...
,因为这些数字中的所有数字都必须是唯一的,并且数字中的第一位不能为零。 / p>
可以通过使用select/3
来减少数字值的每次选择来减小可用值的范围,从而提高代码的整体速度 ,而不是使所有选择都不受影响域Digits
与member/2
。这将大大减少组合选择空间,并且通过消除不等式检查,所有选择的数字将有所不同。标签cryptarithmetic-puzzle的信息页和“问答”条目应对此技术进行更多讨论和/或举例说明(标签zebra-puzzle)。