我正在关注Learn Prolog Now!并正在关注Exercise 2.4。
我found here似乎解决了一个解决方案,但并非完全解决:
word(astante, a,s,t,a,n,t,e).
word(astoria, a,s,t,o,r,i,a).
word(baratto, b,a,r,a,t,t,o).
word(cobalto, c,o,b,a,l,t,o).
word(pistola, p,i,s,t,o,l,a).
word(statale, s,t,a,t,a,l,e).
crossword(V1,V2,V3,H1,H2,H3) :-
word(V1, _, V1H1, _, V1H2, _, V1H3, _),
word(V2, _, V2H1, _, V2H2, _, V2H3, _),
word(V3, _, V3H1, _, V3H2, _, V3H3, _),
word(H1, _, V1H1, _, V2H1, _, V3H1, _),
word(H2, _, V1H2, _, V2H2, _, V3H2, _),
word(H3, _, V1H3, _, V2H3, _, V3H3, _).
这会产生以下结果:
H1 = astoria
H2 = baratto
H3 = statale
V1 = astante
V2 = cobalto
V3 = pistola ? ;
H1 = astante
H2 = cobalto
H3 = pistola
V1 = astoria
V2 = baratto
V3 = statale ? ;
H1 = astoria
H2 = cobalto
H3 = pistola
V1 = astoria
V2 = cobalto
V3 = pistola ? ;
H1 = baratto
H2 = baratto
H3 = statale
V1 = baratto
V2 = baratto
V3 = statale ? ;
H1 = cobalto
H2 = baratto
H3 = statale
V1 = cobalto
V2 = baratto
V3 = statale ? ;
H1 = astante
H2 = baratto
H3 = statale
V1 = astante
V2 = baratto
V3 = statale ? ;
其中只有2个是实用的:
H1 = astoria
H2 = baratto
H3 = statale
V1 = astante
V2 = cobalto
V3 = pistola ? ;
H1 = astante
H2 = cobalto
H3 = pistola
V1 = astoria
V2 = baratto
V3 = statale ? ;
因为其他3个解决方案包含重复项,所以它们不是问题的可行答案。
如何添加填字游戏规则,让它只返回V1,V2,V3,H1,H2,H3都是唯一的结果?
答案 0 :(得分:1)
您可以使用这样的程序来确保值不同:
all_dif([]).
all_dif([A|Tail]):-
all_dif(Tail, A),
all_dif(Tail).
all_dif([], _).
all_dif([B|Tail], A):-
dif(A,B),
all_dif(Tail, A).
并使用all_dif([V1,V2,V3,H1,H2,H3])
答案 1 :(得分:1)
一种常用技术利用select/3来获得回溯的独特替代元素:
crossword(V1,V2,V3,H1,H2,H3) :-
selects(
[[V1, _, V1H1, _, V1H2, _, V1H3, _],
[V2, _, V2H1, _, V2H2, _, V2H3, _],
[V3, _, V3H1, _, V3H2, _, V3H3, _],
[H1, _, V1H1, _, V2H1, _, V3H1, _],
[H2, _, V1H2, _, V2H2, _, V3H2, _],
[H3, _, V1H3, _, V2H3, _, V3H3, _]
],
[[a,s,t,a,n,t,e],
[a,s,t,o,r,i,a],
[b,a,r,a,t,t,o],
[c,o,b,a,l,t,o],
[p,i,s,t,o,l,a],
[s,t,a,t,a,l,e]
]).
selects([], []).
selects([[W|Cs]|Ws], L) :-
select(Cs, L, R),
selects(Ws, R),
atom_chars(W, Cs).
这显然是您已经找到的非常简单的解决方案的替代方法。
select / 3也可用于检查列表中是否没有重复项:
crossword(V1,V2,V3,H1,H2,H3) :-
word(V1, _, V1H1, _, V1H2, _, V1H3, _),
word(V2, _, V2H1, _, V2H2, _, V2H3, _),
word(V3, _, V3H1, _, V3H2, _, V3H3, _),
word(H1, _, V1H1, _, V2H1, _, V3H1, _),
word(H2, _, V1H2, _, V2H2, _, V3H2, _),
word(H3, _, V1H3, _, V2H3, _, V3H3, _),
maplist(nodup([V1,V2,V3,H1,H2,H3]), [V1,V2,V3,H1,H2,H3]).
nodup(L, E) :- select(E, L, R), \+ memberchk(E, R).
最后,由于sort / 2删除了重复项,因此最简单的检查可能是
crossword(V1,V2,V3,H1,H2,H3) :-
word(V1, _, V1H1, _, V1H2, _, V1H3, _),
word(V2, _, V2H1, _, V2H2, _, V2H3, _),
word(V3, _, V3H1, _, V3H2, _, V3H3, _),
word(H1, _, V1H1, _, V2H1, _, V3H1, _),
word(H2, _, V1H2, _, V2H2, _, V3H2, _),
word(H3, _, V1H3, _, V2H3, _, V3H3, _),
sort([V1,V2,V3,H1,H2,H3], [_,_,_,_,_,_]).