我正试图弄清楚如何在序言中解决以下难题。
我需要创建一个谓词seven_digit_puzzle(Result)。提出了遵循以下规则的八位数难题的所有可能解决方案:
结果= [7,4,1,3,6,8,5,2]
答案 0 :(得分:3)
您可以使用CLP(FD)解决问题。条件 两个相邻单元格之间的距离不为一 无需表达即可表达:
ns(X, Y) :-
X #\= Y+1,
X+1 #\= Y.
由于当前情况,无需进行修改 (#/ \)/ 2可以用(,)/ 2代替。与all_different / 1一起,该问题可以表示为:
riddle(L) :-
L = [A,B,C,D,E,F,G,H],
L ins 1..8,
all_different(L),
/* horizontal */
ns(B, E),
ns(A, C),
ns(C, F),
ns(F, H),
ns(D, G),
/* vertical */
ns(B, C),
ns(C, D),
ns(E, F),
ns(F, G),
/* search solution */
label(L).
运行它,我得到以下解决方案:
Jekejeke Prolog 3, Runtime Library 1.3.0
(c) 1985-2018, XLOG Technologies GmbH, Switzerland
?- riddle([7,4,1,3,6,8,5,2]).
Yes
?- findall(hit,riddle(_),L), length(L,N),
write(N), nl, fail; true.
1656
Yes
编辑31.07.2018:
这留作家庭作业。如果为从左下到右上的对角线以及从 从左上到右下,系统变得更加紧凑,并且仅生成以下四个解决方案:
?- riddle(L).
L = [2,5,8,6,3,1,4,7] ;
L = [2,6,8,5,4,1,3,7] ;
L = [7,3,1,4,5,8,6,2] ;
L = [7,4,1,3,6,8,5,2] ;
No
答案 1 :(得分:1)
/*
2,5,
1,3,6,8
4,7,
*/
riddle_p(R) :-
permutation([1,2,3,4,5,6,7,8],R),
maplist(no_diff_1(R), [[2,5],[1,3,6,8],[4,7],[2,3,4],[5,6,7]]).
no_diff_1(R,[A,B|Is]) :-
nth1(A,R,X), nth1(B,R,Y), abs(X-Y) > 1,
!, no_diff_1(R,[B|Is]).
no_diff_1(_,[_]).
在SWI-Prolog中运行,它比clp(fd)解决方案要快得多。