Решение логических задач на Lisp

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

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

Создаю повторно тему, с прошлой возникли какие-то технические трудности. Суть задачи в следующем: К реке подъехали 4 рыцаря с оруженосцами и обнаружили одну трехместную лодку. Как им переправиться на другой берег, если все оруженосцы наотрез отказались оставаться в обществе незнакомых рыцарей? Прошу помощи с решением данной задачи, если у вас есть готовое решение, то буду очень признателен. Если нет, то помоги хоть идеей. Мне удалось сделать ;Функция opposite позволяет менять местоположение путника
Листинг программы
  1. (defun opposite(side)
  2. (cond
  3. ((equal side 'e) 'w)
  4. ((equal side 'w) 'e)
  5. )
  6. )
  7. ;Функция takes позволяет перевозить в лодке пассажиров, но генерирует много ненужных последовательностей
  8. (defun takes (state n1 n2 n3)
  9. (labels ((test(state num1 num2 num3 e boat)
  10. (cond
  11. ((null state) nil)
  12. ((= e 0)(if
  13. (and (> num1 -1)(> num2 -1)(> num3 -1))
  14. (if (and
  15. (equal (nth num1 state) (nth num2 state))
  16. (equal (nth num1 state) (nth num3 state))
  17. (equal (nth num1 state) (car (last state))))
  18. (test state num1 num2 num3 (+ e 1) boat)
  19. nil
  20. )
  21. ))
  22. ((= 0 num1)(append (list(opposite (nth 0 state))) (test (cdr state) (setf num1 -1) (- num2 1)(- num3 1) e (- boat 1))))
  23. ((= 0 num2)(append (list(opposite (nth 0 state))) (test (cdr state) (- num1 1) (setf num2 -1)(- num3 1) e (- boat 1))))
  24. ((= 0 num3)(append (list(opposite (nth 0 state))) (test (cdr state) (- num1 1) (- num2 1)(setf num3 -1) e (- boat 1))))
  25. ((= 0 boat)(append (list(opposite (nth 0 state)))))
  26. (t (append (list (car state)) (test (cdr state) (- num1 1)(- num2 1)(- num3 1) e (- boat 1))))
  27. )
  28. )
  29. )
  30. (test state n1 n2 n3 0 (- (length state) 1))
  31. )
  32. )
  33. ;Функция testiter перебирает всевозможные комбинации из трех чисел. Первым параметром приходит тот, кто перевозит - он не изменяется.
  34. (defun testiter (state n n1 n2)
  35. (cond ((> n2 (- (length state) 2)) nil)
  36. ((> n1 (- (length state) 2)) (append (list (takes state n n1 n2)) (testiter state n 0 (+ n2 1))))
  37. (t (append (list (takes state n n1 n2))(testiter state n (+ n1 1) n2)))
  38. )
  39. )
  40. ;Функция del удаляет одинаковые комбинации ходов.
  41. (defun del(lst)
  42. (labels(
  43. (temp (a b len)
  44. (cond
  45. ((null a) nil)
  46. ((equal (car a) (car b))(temp (cdr a) (cddr a) (- (length lst) 1)))
  47. ((= len 0) (append (list (car a))(temp (cdr a) (cddr a) (- (length lst) 1))))
  48. (t (temp a (cdr b) (- len 1)))
  49. )
  50. )
  51. )
  52. (temp lst (cdr lst) (- (length lst) 1))
  53. )
  54. )
  55. ; Функции *-side возвращают, где находится тот или иной путник.
  56. (defun r1-side (state)(nth 0 state))
  57. (defun r2-side (state)(nth 1 state))
  58. (defun r3-side (state)(nth 2 state))
  59. (defun r4-side (state)(nth 3 state))
  60. (defun o1-side (state)(nth 4 state))
  61. (defun o2-side (state)(nth 5 state))
  62. (defun o3-side (state)(nth 6 state))
  63. (defun o4-side (state)(nth 7 state))
  64. (defun o4-side (state)(nth 8 state))
  65. ;Функция safe проверяет, можно ли сделать ход. Суть состоит в том, что происходит проверка, если рыцарь и оруженосец на разных берегах и какой-то рыцарь на берегу с этим оруженосцем.
  66. (defun safe (state)
  67. (cond
  68. ((and (or (equal (r2-side state) (o1-side state)) (equal (r3-side state) (o1-side state))(equal (r4-side state) (o1-side state)))(not (equal (r1-side state) (o1-side state)))) nil)
  69. ((and (or (equal (r1-side state) (o2-side state)) (equal (r3-side state) (o2-side state))(equal (r4-side state) (o2-side state)))(not (equal (r2-side state) (o2-side state)))) nil)
  70. ((and (or (equal (r2-side state) (o3-side state)) (equal (r1-side state) (o3-side state))(equal (r4-side state) (o3-side state)))(not (equal (r3-side state) (o3-side state)))) nil)
  71. ((and (or (equal (r2-side state) (o4-side state)) (equal (r3-side state) (o4-side state))(equal (r1-side state) (o4-side state)))(not (equal (r4-side state) (o4-side state)))) nil)
  72. (t state)
  73. )
  74. )
  75. ;Функция checkSafe данная функция применяет функцию safe к каждому элементу списка
  76. (defun checkSafe(lst)
  77. (cond ((null lst) nil)
  78. (t (append (list (safe (car lst))) (checkSafe (cdr lst))))
  79. )
  80. )
  81. ;Функция pos_move возвращает ходы, которые применимы для входящего состояния
  82. (defun pos_move(state)
  83. (del (append (remove 'NIL (checkSafe (del (testiter state 0 0 0))))
  84. (remove 'NIL (checkSafe (del (testiter state 1 0 0))))
  85. (remove 'NIL (checkSafe (del (testiter state 2 0 0))))
  86. (remove 'NIL (checkSafe (del (testiter state 3 0 0))))
  87. (remove 'NIL (checkSafe (del (testiter state 4 0 0))))
  88. (remove 'NIL (checkSafe (del (testiter state 5 0 0))))
  89. (remove 'NIL (checkSafe (del (testiter state 6 0 0))))
  90. (remove 'NIL (checkSafe (del (testiter state 7 0 0))))
  91. )
  92. )
  93. )
  94. ;Функция checkGoal проверяет есть ли в списке возможных ходов, наше целевое значение, если да возвращает true, иначе nil
  95. (defun checkGoal (state goal)
  96. (cond
  97. ((null state) nil)
  98. ((equal (car state) goal) T)
  99. (t (checkGoal (cdr state) goal))
  100. )
  101. )
;Функция path должна реализовывать как раз поиск в глубину и возвращать путь Как составить эту функцию? С этим и возникли основные трудности. Буду очень признателен за помощь.

Решение задачи: «Решение логических задач на Lisp»

textual
Листинг программы
  1. ;Функция opposite позволяет менять местоположение путника
  2. (defun opposite(side)
  3.     (cond
  4.         ((equal side 'e) 'w)
  5.         ((equal side 'w) 'e)
  6.     )
  7. )
  8.  
  9. ;Функция takes позволяет перевозить в лодке пассажиров, но генерирует много ненужных последовательностей
  10. (defun takes (state n1 n2 n3)
  11.     (labels ((test(state num1 num2 num3 e boat)
  12.                 (cond
  13.                     ((null state) nil)
  14.                     ((= e 0)(if
  15.                         (and (> num1 -1)(> num2 -1)(> num3 -1))
  16.                                 (if (and
  17.                                     (equal (nth num1 state) (nth num2 state))
  18.                                     (equal (nth num1 state) (nth num3 state))
  19.                                     (equal (nth num1 state) (car (last state))))
  20.                                         (test state num1 num2 num3 (+ e 1) boat)
  21.                                         nil
  22.                                 )
  23.                     ))
  24.                     ((= 0 num1)(append (list(opposite (nth 0 state))) (test (cdr state) (setf num1 -1) (- num2 1)(- num3 1) e (- boat 1))))
  25.                     ((= 0 num2)(append (list(opposite (nth 0 state))) (test (cdr state) (- num1 1) (setf num2 -1)(- num3 1) e (- boat 1))))
  26.                     ((= 0 num3)(append (list(opposite (nth 0 state))) (test (cdr state) (- num1 1) (- num2 1)(setf num3 -1) e (- boat 1))))
  27.                     ((= 0 boat)(append (list(opposite (nth 0 state)))))
  28.                     (t (append (list (car state)) (test (cdr state) (- num1 1)(- num2 1)(- num3 1) e (- boat 1))))
  29.                 )
  30.             )
  31.         )
  32.     (test state n1 n2 n3 0 (- (length state) 1))
  33.     )
  34. )
  35.  
  36. ;Функция testiter перебирает всевозможные комбинации из трех чисел. Первым параметром приходит тот, кто перевозит - он не изменяется.
  37. (defun testiter (state n n1 n2)
  38.     (cond   ((> n2 (- (length state) 2)) nil)
  39.             ((> n1 (- (length state) 2)) (append (list (takes state n n1 n2)) (testiter state n 0 (+ n2 1))))
  40.             (t (append (list (takes state n n1 n2))(testiter state n (+ n1 1) n2)))
  41.     )
  42. )
  43.  
  44. ;Функция del удаляет одинаковые комбинации ходов.
  45. (defun del(lst)
  46.     (labels(
  47.             (temp (a b len)
  48.                 (cond
  49.                     ((null a) nil)
  50.                     ((equal (car a) (car b))(temp (cdr a) (cddr a) (- (length lst) 1)))
  51.                     ((= len 0) (append (list (car a))(temp (cdr a) (cddr a) (- (length lst) 1))))
  52.                     (t (temp a (cdr b) (- len 1)))
  53.                 )
  54.             )
  55.         )
  56.         (temp lst (cdr lst) (- (length lst) 1))
  57.     )
  58. )
  59.  
  60. ; Функции *-side возвращают, где находится тот или иной путник.
  61. (defun r1-side (state)(nth 0 state))
  62. (defun r2-side (state)(nth 1 state))
  63. (defun r3-side (state)(nth 2 state))
  64. (defun r4-side (state)(nth 3 state))
  65. (defun o1-side (state)(nth 4 state))
  66. (defun o2-side (state)(nth 5 state))
  67. (defun o3-side (state)(nth 6 state))
  68. (defun o4-side (state)(nth 7 state))
  69. (defun o4-side (state)(nth 8 state))
  70.  
  71. ;Функция safe проверяет, можно ли сделать ход. Суть состоит в том, что происходит проверка, если рыцарь и оруженосец на разных берегах и какой-то рыцарь на берегу с этим оруженосцем.
  72. (defun safe (state)
  73.     (cond
  74.         ((and (or (equal (r2-side state) (o1-side state)) (equal (r3-side state) (o1-side state))(equal (r4-side state) (o1-side state)))(not (equal (r1-side state) (o1-side state)))) nil)
  75.         ((and (or (equal (r1-side state) (o2-side state)) (equal (r3-side state) (o2-side state))(equal (r4-side state) (o2-side state)))(not (equal (r2-side state) (o2-side state)))) nil)
  76.         ((and (or (equal (r2-side state) (o3-side state)) (equal (r1-side state) (o3-side state))(equal (r4-side state) (o3-side state)))(not (equal (r3-side state) (o3-side state)))) nil)
  77.         ((and (or (equal (r2-side state) (o4-side state)) (equal (r3-side state) (o4-side state))(equal (r1-side state) (o4-side state)))(not (equal (r4-side state) (o4-side state)))) nil)
  78.         (t state)
  79.     )
  80. )
  81.  
  82. ;Функция checkSafe данная функция применяет функцию safe к каждому элементу списка
  83. (defun checkSafe(lst)
  84.     (cond ((null lst) nil)
  85.         (t (append (list (safe (car lst))) (checkSafe (cdr lst))))
  86.     )
  87. )
  88.  
  89. ;Функция pos_move возвращает ходы, которые применимы для входящего состояния
  90. (defun pos_move(state)
  91.     (del (append (remove 'NIL (checkSafe (del (testiter state 0 0 0))))
  92.             (remove 'NIL (checkSafe (del (testiter state 1 0 0))))
  93.             (remove 'NIL (checkSafe (del (testiter state 2 0 0))))
  94.             (remove 'NIL (checkSafe (del (testiter state 3 0 0))))
  95.             (remove 'NIL (checkSafe (del (testiter state 4 0 0))))
  96.             (remove 'NIL (checkSafe (del (testiter state 5 0 0))))
  97.             (remove 'NIL (checkSafe (del (testiter state 6 0 0))))
  98.             (remove 'NIL (checkSafe (del (testiter state 7 0 0))))
  99.         )
  100.     )
  101. )
  102.  
  103. ;Функция checkGoal проверяет есть ли в списке возможных ходов, наше целевое значение, если да возвращает true, иначе nil
  104. (defun checkGoal (state goal)
  105.     (cond
  106.         ((null state) nil)
  107.         ((equal (car state) goal) (car state))
  108.         (t (checkGoal (cdr state) goal))
  109.     )
  110. )
  111.  
  112. ;Функция checkWas проверяет есть ли в списке уже пройденных вершин, вершины из списка возможных ходов
  113. (defun checkWas (st b)
  114.     (labels
  115.         ((temp (state been_list len)
  116.             (cond
  117.                 ((null state) nil)
  118.                 ((null been_list) state)
  119.                 ((equal (car state) (car been_list)) (temp (cdr state) b (- (length b) 1)))
  120.                 ((= len 0) (append (list (car state)) (temp (cdr state) b (- (length b) 1))))
  121.                 (t (temp state (cdr been_list) (- len 1)))
  122.             )
  123.         ))
  124.     (temp st b (- (length b) 1))
  125.     )
  126. )
  127.  
  128.  
  129. ;Функция path
  130. (defun path(state goal been_list)
  131.     (cond
  132.         ((null state) nil)
  133.         ((not (null (checkGoal been_list goal))) (reverse (cons (checkGoal state goal) been_list)))
  134.         ((not (null (checkGoal state goal))) (reverse (cons (checkGoal state goal) been_list)))
  135.         ((not (null (checkWas state been_list)))  
  136.                 (or
  137.                     (path (pos_move (car (checkWas state been_list))) goal (cons (car (checkWas state been_list)) been_list))
  138.                     (path (cdr (checkWas state been_list)) goal been_list)
  139.                 )
  140.         )
  141.     )
  142. )
  143.  
  144. (print (path '((w w w w w w w w w)) '(e e e e e e e e e) nil))

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


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

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

11   голосов , оценка 4.182 из 5

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

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

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