Задача на рекурсию - Prolog
Формулировка задачи:
Помогите пожалуйста. Есть задача: Дана последовательность a с элементами из множества {0,1}. Проводятся следующие действия. Если a имеет вид 1,0,1,… , то она укорачивается на первые три элемента. В противном случае начальный элемент последовательности переносится в её конец. Указанные действия повторяются до тех пор, пока имеется возможность укоротить текущую последовательность. Требуется составить рекурсивную программу, имитирующую эти действия и возвращающую по исходной последовательности a результирующую последовательность b или сообщение, что b - пустое множество.
Есть готовое решение на C#, но на Prolog перевести не получается.
Решение задачи: «Задача на рекурсию»
textual
Листинг программы
cut_seq_main :-
N = 50,
S = [1, 0, 1],
gen_seq(N, L),
format('Входное множество: ~w~n', [L]),
format('Фильтр: ~w~n', [S]),
cut_seq(S, L, L1),
format('Выходное множество: ~w~n', [L1]).
gen_seq(0, []).
gen_seq(N, [X | R]) :-
N > 0,
X is random(2),
N1 is N - 1,
gen_seq(N1, R).
cut_seq(Shape, Seq, SeqOut) :-
cut_seq_once(Shape, Seq, Seq1),
Seq \= Seq1,
!,
cut_seq(Shape, Seq1, SeqOut).
cut_seq(_, Seq, Seq) :-
!.
cut_seq_once(_, [], []).
cut_seq_once(Shape, Seq, Rest) :-
append(Shape, Tail, Seq),
!,
cut_seq_once(Shape, Tail, Rest).
cut_seq_once(Shape, [Head | Tail], [Head | Rest]) :-
cut_seq_once(Shape, Tail, Rest).
Объяснение кода листинга программы
- В первой строке объявлены следующие переменные: N (количество элементов в исходном множестве), S (фильтр, последовательность 1,0,1), L (исходное множество), L1 (результат).
- Вторая строка говорит, что если N=0, то генерировать последовательность не нужно, а если N>0, то генерируется случайное число X и вычисляется N1=N-1, и рекурсивно вызывается gen_seq(N1, R).
- Третья строка говорит, что если N=0, то результат пустой список, иначе рекурсивно вызывается cut_seq(Shape, Seq, Seq1), где Seq1 - это результат предыдущего вызова, и если Seq не равно Seq1, то продолжается рекурсия, иначе рекурсия прекращается.
- Четвертая строка говорит, что если Shape=[] (пустое множество), то результат пустой список.
- Пятая строка говорит, что если Shape=[Head|Tail] (не пустое множество), то рекурсивно вызывается cut_seq_once(Shape, Tail, Rest), где Rest - это результат предыдущего вызова, и если Tail не пустое множество, то добавляется Head в начало Rest и рекурсивно вызывается cut_seq_once(Shape, Tail, Rest).
- Шестая строка говорит, что если Shape=[Head|Tail] (не пустое множество), то результат это список, в котором первым элементом является Head, а остальное - это результат предыдущего вызова.