Спецификация менее ясна, чем должна быть, но вот мое понимание: зашифрованная последовательность состоит из следующего по порядку:
- некоторый префикс
- дублированный разделитель с указанием начала смещенной последовательности
- самой смещенной "конечной" последовательности
- дублированного разделителя, указывающего конец смещенной последовательности
- суффикс
Расшифрованная последовательность содержит те же части в другом порядке:
- префикс
- разделитель «начало» (только один раз)
- конец "разделитель (только один раз)
- суффикс
- « последняя »часть
Полезной стратегией для решения этой проблемы является написание отдельных предикатов для идентификации частей зашифрованной последовательности и для объединения этих частей вместе, чтобы получить расшифрованную последовательность. Как правило, в Прологе (даже больше, чем в других языках программирования) вы должны стараться распознавать отдельные подзадачи и писать отдельные предикаты для их решения.
Например:
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).