Задача на рекурсию - Prolog

Узнай цену своей работы

Формулировка задачи:

Помогите пожалуйста. Есть задача: Дана последовательность a с элементами из множества {0,1}. Проводятся следующие действия. Если a имеет вид 1,0,1,… , то она укорачивается на первые три элемента. В противном случае начальный элемент последовательности переносится в её конец. Указанные действия повторяются до тех пор, пока имеется возможность укоротить текущую последовательность. Требуется составить рекурсивную программу, имитирующую эти действия и возвращающую по исходной последовательности a результирующую последовательность b или сообщение, что b - пустое множество. Есть готовое решение на C#, но на Prolog перевести не получается.
Листинг программы
  1. static void Main(string[] args)
  2. {
  3. //Создадим случайное множество
  4. List<int> A1 = new List<int>();
  5. Random rnd = new Random();
  6. for (int i = 0; i < 50; i++)
  7. {
  8. A1.Add(rnd.Next(2));
  9. }
  10. //И еще одно такое-же для рекурсии
  11. List<int> A2 = new List<int>();
  12. A2.AddRange(A1);
  13. Console.WriteLine("Входное множество");
  14. OutConsole(A1);
  15. // Проверка на пустой результат
  16. // A2.Clear(); A2.Add(1); A2.Add(0); A2.Add(1); A2.Add(1); A2.Add(0); A2.Add(1);
  17. // Обработаем множество в цикле
  18. var B1 = processingLoop(A1);
  19. if (B1.Count == 0) { Console.WriteLine("b - пустое множество"); }
  20. else { Console.WriteLine("Выходное множество обработанное в цикле"); OutConsole(B1);};
  21. // Обработаем множество рекурсивно
  22. List<int> B2 = new List<int>();
  23. int cnt;
  24. processingRecursion(A2,A2.Count,out B2,out cnt);
  25. if (B2.Count == 0) Console.WriteLine("b - пустое множество");
  26. else { Console.WriteLine("Выходное множество обработанное рекурсивно"); OutConsole(B2); };
  27. Console.ReadKey();
  28. }
  29. //
  30. private static bool processingRecursion(List<int> A, int cntStopA, out List<int> B, out int cntStopB)
  31. {
  32. //выход из рекурсии
  33. if (A.Count < 3||cntStopA==0) { cntStopB=0; B=A; return true; }
  34. if (A[0] == 1 && A[1] == 0 && A[2] == 1)
  35. { A.RemoveRange(0, 3); B = A; cntStopB = A.Count; return processingRecursion(B , cntStopB, out B, out cntStopB); }
  36. A.Add(A.ElementAt(0));
  37. A.RemoveAt(0);
  38. B=A;
  39. cntStopB = cntStopA - 1;
  40. return processingRecursion(B, cntStopB, out B, out cntStopB);
  41. }
  42. private static List<int> processingLoop(List<int> A)
  43. {
  44. //Для контроля остановки
  45. int cntStop = A.Count;
  46. while(cntStop!=0&&A.Count>=3)
  47. {
  48. if (A[0] == 1 && A[1] == 0 && A[2] == 1) { A.RemoveRange(0, 3); cntStop = A.Count; }
  49. else { A.Add(A.ElementAt(0)); A.RemoveAt(0); cntStop--; }
  50. }
  51. return A;
  52. }
  53. private static void OutConsole(List<int>lst )
  54. {
  55. foreach (var item in lst)
  56. {
  57. Console.Write(item.ToString());
  58. }
  59. Console.WriteLine();
  60. }

Решение задачи: «Задача на рекурсию»

textual
Листинг программы
  1. cut_seq_main :-
  2.     N = 50,
  3.     S = [1, 0, 1],
  4.     gen_seq(N, L),
  5.     format('Входное множество: ~w~n', [L]),
  6.     format('Фильтр: ~w~n', [S]),
  7.     cut_seq(S, L, L1),
  8.     format('Выходное множество: ~w~n', [L1]).
  9.    
  10. gen_seq(0, []).
  11. gen_seq(N, [X | R]) :-
  12.     N > 0,
  13.     X is random(2),
  14.     N1 is N - 1,
  15.     gen_seq(N1, R).
  16.  
  17. cut_seq(Shape, Seq, SeqOut) :-
  18.   cut_seq_once(Shape, Seq, Seq1),
  19.   Seq \= Seq1,
  20.   !,
  21.   cut_seq(Shape, Seq1, SeqOut).
  22. cut_seq(_, Seq, Seq) :-
  23.   !.
  24.  
  25. cut_seq_once(_, [], []).
  26. cut_seq_once(Shape, Seq, Rest) :-
  27.     append(Shape, Tail, Seq),
  28.     !,
  29.     cut_seq_once(Shape, Tail, Rest).
  30. cut_seq_once(Shape, [Head | Tail], [Head | Rest]) :-
  31.     cut_seq_once(Shape, Tail, Rest).

Объяснение кода листинга программы

  1. В первой строке объявлены следующие переменные: N (количество элементов в исходном множестве), S (фильтр, последовательность 1,0,1), L (исходное множество), L1 (результат).
  2. Вторая строка говорит, что если N=0, то генерировать последовательность не нужно, а если N>0, то генерируется случайное число X и вычисляется N1=N-1, и рекурсивно вызывается gen_seq(N1, R).
  3. Третья строка говорит, что если N=0, то результат пустой список, иначе рекурсивно вызывается cut_seq(Shape, Seq, Seq1), где Seq1 - это результат предыдущего вызова, и если Seq не равно Seq1, то продолжается рекурсия, иначе рекурсия прекращается.
  4. Четвертая строка говорит, что если Shape=[] (пустое множество), то результат пустой список.
  5. Пятая строка говорит, что если Shape=[Head|Tail] (не пустое множество), то рекурсивно вызывается cut_seq_once(Shape, Tail, Rest), где Rest - это результат предыдущего вызова, и если Tail не пустое множество, то добавляется Head в начало Rest и рекурсивно вызывается cut_seq_once(Shape, Tail, Rest).
  6. Шестая строка говорит, что если Shape=[Head|Tail] (не пустое множество), то результат это список, в котором первым элементом является Head, а остальное - это результат предыдущего вызова.

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

12   голосов , оценка 4.167 из 5

Нужна аналогичная работа?

Оформи быстрый заказ и узнай стоимость

Бесплатно
Оформите заказ и авторы начнут откликаться уже через 10 минут