fork download
  1. (defstruct estado
  2. ml cl mr cr side camino)
  3.  
  4. (defun estado-valido-p (st)
  5. (let ((ml (estado-ml st)) (cl (estado-cl st))
  6. (mr (estado-mr st)) (cr (estado-cr st)))
  7. (and (>= ml 0) (<= ml 3) (>= cl 0) (<= cl 3)
  8. (>= mr 0) (<= mr 3) (>= cr 0) (<= cr 3)
  9. (or (= ml 0) (>= ml cl))
  10. (or (= mr 0) (>= mr cr)))))
  11.  
  12. (defun mover (st m c)
  13. (let ((side (estado-side st)))
  14. (if (= side 0)
  15. (make-estado :ml (- (estado-ml st) m) :cl (- (estado-cl st) c)
  16. :mr (+ (estado-mr st) m) :cr (+ (estado-cr st) c)
  17. :side 1
  18. :camino (append (estado-camino st) (list (format nil "~dM~dC ->" m c))))
  19. (make-estado :ml (+ (estado-ml st) m) :cl (+ (estado-cl st) c)
  20. :mr (- (estado-mr st) m) :cr (- (estado-cr st) c)
  21. :side 0
  22. :camino (append (estado-camino st) (list (format nil "~dM~dC <-" m c)))))))
  23.  
  24. (defun iguales (a b)
  25. (and (= (estado-ml a) (estado-ml b)) (= (estado-cl a) (estado-cl b))
  26. (= (estado-mr a) (estado-mr b)) (= (estado-cr a) (estado-cr b))
  27. (= (estado-side a) (estado-side b))))
  28.  
  29. (defun repetido-p (nuevo historial)
  30. (some (lambda (e) (iguales e nuevo)) historial))
  31.  
  32. (defparameter *viajes* '((2 0) (0 2) (1 1) (1 0) (0 1)))
  33.  
  34. ;; Contador global para identificar las soluciones
  35. (defparameter *contador-soluciones* 0)
  36.  
  37. (defun resolver (estado final historial)
  38. (when (iguales estado final)
  39. (incf *contador-soluciones*)
  40. (mostrar-solucion (reverse (cons estado historial)) *contador-soluciones*)
  41. ;; NO ponemos return-from para que siga buscando más caminos
  42. (return-from resolver nil))
  43.  
  44. (dolist (v *viajes*)
  45. (let* ((m (first v))
  46. (c (second v))
  47. (nuevo (mover estado m c)))
  48. (when (and (estado-valido-p nuevo)
  49. (not (repetido-p nuevo historial)))
  50. (resolver nuevo final (cons estado historial))))))
  51.  
  52. (defun personas (m c)
  53. (concatenate 'string
  54. (make-string m :initial-element #\M)
  55. (make-string c :initial-element #\C)))
  56.  
  57. (defun lado-a-string (m c)
  58. (format nil "[~3a]" (personas m c)))
  59.  
  60. (defun mostrar-paso (anterior actual)
  61. (let ((side (estado-side anterior))
  62. (movimiento (car (last (estado-camino actual)))))
  63. (format t "~%~a ~a ~a | Acción: ~a"
  64. (lado-a-string (estado-ml anterior) (estado-cl anterior))
  65. (if (= side 0) " B ~~~~ " " ~~~~ B ")
  66. (lado-a-string (estado-mr anterior) (estado-cr anterior))
  67. movimiento)))
  68.  
  69. (defun mostrar-solucion (camino n)
  70. (format t "~%~%====================================")
  71. (format t "~%SOLUCIÓN NÚMERO ~d" n)
  72. (format t "~%====================================")
  73. (loop for (a b) on camino while b do (mostrar-paso a b))
  74. (let ((u (car (last camino))))
  75. (format t "~%~a ~~~~ B ~a | ¡Llegaron!"
  76. (lado-a-string (estado-ml u) (estado-cl u))
  77. (lado-a-string (estado-mr u) (estado-cr u)))))
  78.  
  79. (defun main ()
  80. (setf *contador-soluciones* 0) ; Reiniciar contador
  81. (let ((inicio (make-estado :ml 3 :cl 3 :mr 0 :cr 0 :side 0 :camino '()))
  82. (fin (make-estado :ml 0 :cl 0 :mr 3 :cr 3 :side 1 :camino '())))
  83. (resolver inicio fin '())
  84. (format t "~%~%Búsqueda finalizada. Se encontraron ~d soluciones.~%" *contador-soluciones*)))
  85.  
  86. (main)
Success #stdin #stdout 0.02s 30596KB
stdin
Standard input is empty
stdout

====================================
SOLUCIÓN NÚMERO 1
====================================
[MMMCCC]  B ~~~~    [   ]  | Acción: 0M2C ->
[MMMC]    ~~~~ B  [CC ]  | Acción: 0M1C <-
[MMMCC]  B ~~~~    [C  ]  | Acción: 0M2C ->
[MMM]    ~~~~ B  [CCC]  | Acción: 0M1C <-
[MMMC]  B ~~~~    [CC ]  | Acción: 2M0C ->
[MC ]    ~~~~ B  [MMCC]  | Acción: 1M1C <-
[MMCC]  B ~~~~    [MC ]  | Acción: 2M0C ->
[CC ]    ~~~~ B  [MMMC]  | Acción: 0M1C <-
[CCC]  B ~~~~    [MMM]  | Acción: 0M2C ->
[C  ]    ~~~~ B  [MMMCC]  | Acción: 1M0C <-
[MC ]  B ~~~~    [MMCC]  | Acción: 1M1C ->
[   ]    ~~ B  [MMMCCC]  | ¡Llegaron!

====================================
SOLUCIÓN NÚMERO 2
====================================
[MMMCCC]  B ~~~~    [   ]  | Acción: 0M2C ->
[MMMC]    ~~~~ B  [CC ]  | Acción: 0M1C <-
[MMMCC]  B ~~~~    [C  ]  | Acción: 0M2C ->
[MMM]    ~~~~ B  [CCC]  | Acción: 0M1C <-
[MMMC]  B ~~~~    [CC ]  | Acción: 2M0C ->
[MC ]    ~~~~ B  [MMCC]  | Acción: 1M1C <-
[MMCC]  B ~~~~    [MC ]  | Acción: 2M0C ->
[CC ]    ~~~~ B  [MMMC]  | Acción: 0M1C <-
[CCC]  B ~~~~    [MMM]  | Acción: 0M2C ->
[C  ]    ~~~~ B  [MMMCC]  | Acción: 0M1C <-
[CC ]  B ~~~~    [MMMC]  | Acción: 0M2C ->
[   ]    ~~ B  [MMMCCC]  | ¡Llegaron!

====================================
SOLUCIÓN NÚMERO 3
====================================
[MMMCCC]  B ~~~~    [   ]  | Acción: 1M1C ->
[MMCC]    ~~~~ B  [MC ]  | Acción: 1M0C <-
[MMMCC]  B ~~~~    [C  ]  | Acción: 0M2C ->
[MMM]    ~~~~ B  [CCC]  | Acción: 0M1C <-
[MMMC]  B ~~~~    [CC ]  | Acción: 2M0C ->
[MC ]    ~~~~ B  [MMCC]  | Acción: 1M1C <-
[MMCC]  B ~~~~    [MC ]  | Acción: 2M0C ->
[CC ]    ~~~~ B  [MMMC]  | Acción: 0M1C <-
[CCC]  B ~~~~    [MMM]  | Acción: 0M2C ->
[C  ]    ~~~~ B  [MMMCC]  | Acción: 1M0C <-
[MC ]  B ~~~~    [MMCC]  | Acción: 1M1C ->
[   ]    ~~ B  [MMMCCC]  | ¡Llegaron!

====================================
SOLUCIÓN NÚMERO 4
====================================
[MMMCCC]  B ~~~~    [   ]  | Acción: 1M1C ->
[MMCC]    ~~~~ B  [MC ]  | Acción: 1M0C <-
[MMMCC]  B ~~~~    [C  ]  | Acción: 0M2C ->
[MMM]    ~~~~ B  [CCC]  | Acción: 0M1C <-
[MMMC]  B ~~~~    [CC ]  | Acción: 2M0C ->
[MC ]    ~~~~ B  [MMCC]  | Acción: 1M1C <-
[MMCC]  B ~~~~    [MC ]  | Acción: 2M0C ->
[CC ]    ~~~~ B  [MMMC]  | Acción: 0M1C <-
[CCC]  B ~~~~    [MMM]  | Acción: 0M2C ->
[C  ]    ~~~~ B  [MMMCC]  | Acción: 0M1C <-
[CC ]  B ~~~~    [MMMC]  | Acción: 0M2C ->
[   ]    ~~ B  [MMMCCC]  | ¡Llegaron!

Búsqueda finalizada. Se encontraron 4 soluciones.