首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何创建将每个值作为唯一值返回规则

如何创建将每个值作为唯一值返回规则
EN

Stack Overflow用户
提问于 2013-06-19 02:03:00
回答 2查看 294关注 0票数 0

我和Learn Prolog Now!一起关注着Exercise 2.4

一个I found here似乎可以解决的解决方案,但不是完全解决:

代码语言:javascript
复制
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, _).

这将产生以下结果:

代码语言:javascript
复制
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个是实用的:

代码语言:javascript
复制
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都是唯一的结果?

EN

回答 2

Stack Overflow用户

发布于 2013-06-19 02:43:52

您可以使用这样的过程来确保值完全不同:

代码语言:javascript
复制
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
EN

Stack Overflow用户

发布于 2013-06-19 05:29:39

一种常见的技术是利用select/3,在回溯上获得唯一的替代元素:

代码语言:javascript
复制
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也可用于检查列表中是否有重复项:

代码语言:javascript
复制
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删除了重复项,所以最简单的检查方法可能是

代码语言:javascript
复制
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], [_,_,_,_,_,_]).
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17175790

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档