从上一篇关于这类谜题的条目中概括我的代码,我们得到
check( Sol, Guess, NValues-NPlaces ) :-
findall( t, (member(E, Guess), member(E, Sol)), Values ),
length( Values, NValues ),
maplist( eq, Sol, Guess, NS),
sum_list( NS, NPlaces).
eq(A,B,X) :- A =:= B -> X=1 ; X=0.
select([X|XS],Dom) :- select(X,Dom,Dom2), select(XS,Dom2).
select([],_).
puzzle( [A,B,C,D] ) :-
Dom = [0, 1, 3, 5, 8, 9], % using hint 3
select( [A,B,C,D], Dom), % with unique digits
maplist( check([A,B,C,D]),
[[2,7,4,1], [4,1,3,2], [9,8,2,6], [5,0,7,9]],
[ 1-0, 2-0, 1-1, 2-1 ] ).
尝试一下:
164 ?- time( puzzle(X) ).
% 33,274 inferences, 0.016 CPU in 0.011 seconds (142% CPU, 2132935 Lips)
X = [9, 0, 1, 3] ;
% 5,554 inferences, 0.016 CPU in 0.002 seconds (780% CPU, 356023 Lips)
false.
或者我们可以内联定义,将它们融合在一起
mmd(Sol):-
%%maplist( dif, [2,7,4,1], Sol), % 1.
maplist( dif, [4,1,3,2], Sol), % 2.
maplist( eq1, Sol, [9,8,2,6], NS4),
sum_list( NS4, 1), % 4.
maplist( eq1, Sol, [5,0,7,9], NS5),
sum_list( NS5, 1), % 5.
select( Sol, [0,1,3,5,8,9]), % 3.
%%findall( t, (member(E, [2,7,4,1]), member(E, Sol)), [_] ), % 1.
findall( t, (member(E, [4,1,3,2]), member(E, Sol)), [_,_] ), % 2.
%%findall( t, (member(E, [9,8,2,6]), member(E, Sol)), [_] ), % 4.
findall( t, (member(E, [5,0,7,9]), member(E, Sol)), [_,_] ). % 5.
eq1(A,B,C) :- (A#=B,C=1 ; dif(A,B),C=0).
重新排列子目标以尽可能地限制搜索空间,因此几乎可以立即找到解决方案,并且整体推论减少了一半以上:
167 ?- time( mmd(S) ).
% 1,219 inferences, 0.000 CPU in 0.001 seconds (0% CPU, Infinite Lips)
S = [9, 0, 1, 3] ;
% 13,714 inferences, 0.000 CPU in 0.001 seconds (0% CPU, Infinite Lips)
false.
正如在另一个答案中首先注意到的那样,并不是所有的线索都是真正需要的,并且删除它们甚至会减少一些额外的小幅度解决这个问题所需的推理数量。