2013-06-18 2 views
0

Я следую вместе с Learn Prolog Now! и смотрел Exercise 2.4.Как создать правило, которое возвращает каждое значение как уникальное

Раствор I 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 решения содержат дубликаты, они не являются жизнеспособными ответами для pr oblem.

Как добавить к правилу кроссворда, чтобы он возвращал результаты только там, где V1, V2, V3, H1, H2, H3 уникальны?

ответ

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

общей методики используют 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). 

Это, безусловно, альтернативный метод для очень простого решения, которое вы уже нашли.

выбрать/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). 

В конце концов, так как сорт/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], [_,_,_,_,_,_]). 
+0

+ 1 Мне нравится 'select/3' и использовать его все время. :) –

Смежные вопросы