Задача на рекурсию - Prolog
Формулировка задачи:
Помогите пожалуйста. Есть задача: Дана последовательность a с элементами из множества {0,1}. Проводятся следующие действия. Если a имеет вид 1,0,1,… , то она укорачивается на первые три элемента. В противном случае начальный элемент последовательности переносится в её конец. Указанные действия повторяются до тех пор, пока имеется возможность укоротить текущую последовательность. Требуется составить рекурсивную программу, имитирующую эти действия и возвращающую по исходной последовательности a результирующую последовательность b или сообщение, что b - пустое множество.
Есть готовое решение на C#, но на Prolog перевести не получается.
Листинг программы
- static void Main(string[] args)
- {
- //Создадим случайное множество
- List<int> A1 = new List<int>();
- Random rnd = new Random();
- for (int i = 0; i < 50; i++)
- {
- A1.Add(rnd.Next(2));
- }
- //И еще одно такое-же для рекурсии
- List<int> A2 = new List<int>();
- A2.AddRange(A1);
- Console.WriteLine("Входное множество");
- OutConsole(A1);
- // Проверка на пустой результат
- // A2.Clear(); A2.Add(1); A2.Add(0); A2.Add(1); A2.Add(1); A2.Add(0); A2.Add(1);
- // Обработаем множество в цикле
- var B1 = processingLoop(A1);
- if (B1.Count == 0) { Console.WriteLine("b - пустое множество"); }
- else { Console.WriteLine("Выходное множество обработанное в цикле"); OutConsole(B1);};
- // Обработаем множество рекурсивно
- List<int> B2 = new List<int>();
- int cnt;
- processingRecursion(A2,A2.Count,out B2,out cnt);
- if (B2.Count == 0) Console.WriteLine("b - пустое множество");
- else { Console.WriteLine("Выходное множество обработанное рекурсивно"); OutConsole(B2); };
- Console.ReadKey();
- }
- //
- private static bool processingRecursion(List<int> A, int cntStopA, out List<int> B, out int cntStopB)
- {
- //выход из рекурсии
- if (A.Count < 3||cntStopA==0) { cntStopB=0; B=A; return true; }
- if (A[0] == 1 && A[1] == 0 && A[2] == 1)
- { A.RemoveRange(0, 3); B = A; cntStopB = A.Count; return processingRecursion(B , cntStopB, out B, out cntStopB); }
- A.Add(A.ElementAt(0));
- A.RemoveAt(0);
- B=A;
- cntStopB = cntStopA - 1;
- return processingRecursion(B, cntStopB, out B, out cntStopB);
- }
- private static List<int> processingLoop(List<int> A)
- {
- //Для контроля остановки
- int cntStop = A.Count;
- while(cntStop!=0&&A.Count>=3)
- {
- if (A[0] == 1 && A[1] == 0 && A[2] == 1) { A.RemoveRange(0, 3); cntStop = A.Count; }
- else { A.Add(A.ElementAt(0)); A.RemoveAt(0); cntStop--; }
- }
- return A;
- }
- private static void OutConsole(List<int>lst )
- {
- foreach (var item in lst)
- {
- Console.Write(item.ToString());
- }
- Console.WriteLine();
- }
Решение задачи: «Задача на рекурсию»
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, а остальное - это результат предыдущего вызова.
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д