Список, в котором есть дубликаты (по очереди), часть из которых необходимо перенести - PullRequest
1 голос
/ 10 июля 2020

Этот вопрос касается типа специальной «криптографии», в которой слово имеет последовательно повторяющиеся буквы. После дубликата следует часть, которая неуместна и должна оказаться в конце списка. Мое правило имеет структуру: крипто (Word1, Word2), где Word1 - это криптография, а Word2 не зашифрован / ответ

изменил код, так как я нашел что-то более близкое к ответу

Что я хочу:

?- crypto([h,a,a,o,m,e,n,n,d,s], L).  
L = [h,a,n,d,s,o,m,e]

Что я получу, если (1 дубликат):

?- crypto([h,a,a,o,m,e,n,d,s], L).  
L = [h,a,n,d,s,o,m,e]

Я попробовал следующий код:

crypto([],[]).
crypto([H|T], List) :-   %is true when its duplicate 
     member(H, T),
     append(Empty_at_first,[Arxh|Telos],[H|T]), 
     append(A,[Ar|Te],Telos),
     ml(Te,3,Result_ml), 
     append([H],Result_ml,Result),
     crypto(Result,List).
crypto([H| T], [H|T1]) :- 
      not(member(H, T)),                     
      crypto(T, T1).

ml([H|T],R):-append(T,[H|[]],R).
ml(A,0,A).

ml([H|T],N,R):-
   N1 is N - 1, ml([H|T],R1), ml(R1,N1,R),!.

1 Ответ

2 голосов
/ 12 июля 2020

Спецификация менее ясна, чем должна быть, но вот мое понимание: зашифрованная последовательность состоит из следующего по порядку:

  • некоторый префикс
  • дублированный разделитель с указанием начала смещенной последовательности
  • самой смещенной "конечной" последовательности
  • дублированного разделителя, указывающего конец смещенной последовательности
  • суффикс

Расшифрованная последовательность содержит те же части в другом порядке:

  • префикс
  • разделитель «начало» (только один раз)
  • конец "разделитель (только один раз)
  • суффикс
  • « последняя »часть

Полезной стратегией для решения этой проблемы является написание отдельных предикатов для идентификации частей зашифрованной последовательности и для объединения этих частей вместе, чтобы получить расшифрованную последовательность. Как правило, в Прологе (даже больше, чем в других языках программирования) вы должны стараться распознавать отдельные подзадачи и писать отдельные предикаты для их решения.

Например:

encrypted_parts(Encrypted, Prefix, X, Y, Suffix, Final) :-
    append(Prefix, L1, Encrypted),
    L1 = [X, X | L2],
    append(Final, L3, L2),
    L3 = [Y, Y | L4],
    Suffix = L4.

Это ведет себя следующим образом:

?- encrypted_parts([h,a,a,o,m,e,n,n,d,s], Prefix, X, Y, Suffix, Final).
Prefix = [h],
X = a,
Y = n,
Suffix = [d, s],
Final = [o, m, e] ;
false.

Он распознает, что a и n являются дублированными разделителями, а [o, m, e] - это промежуточная последовательность, которая должна оказаться в конце расшифрованной последовательности. .

Объединение этих частей очень похоже:

decrypted_parts(Decrypted, Prefix, X, Y, Suffix, Final) :-
    append(Prefix, L1, Decrypted),
    L1 = [X, Y | L2],
    append(Suffix, L3, L2),
    Final = L3.

И наконец:

crypto(Encrypted, Decrypted) :-
    encrypted_parts(Encrypted, Prefix, X, Y, Suffix, Final),
    decrypted_parts(Decrypted, Prefix, X, Y, Suffix, Final).

?- crypto([h,a,a,o,m,e,n,n,d,s], Decrypted).
Decrypted = [h, a, n, d, s, o, m, e] ;
false.

Все это более читаемо с DCG, если вы знаете о их уже:

encrypted(Prefix, X, Y, Suffix, Final) -->
    list(Prefix),
    list([X, X]),
    list(Final),
    list([Y, Y]),
    list(Suffix).

decrypted(Prefix, X, Y, Suffix, Final) -->
    list(Prefix),
    [X],
    [Y],
    list(Suffix),
    list(Final).

list([]) -->
    [].
list([X | Xs]) -->
    [X],
    list(Xs).

crypto_dcg(Encrypted, Decrypted) :-
    phrase(encrypted(Prefix, X, Y, Suffix, Final), Encrypted),
    phrase(decrypted(Prefix, X, Y, Suffix, Final), Decrypted).
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...