fork download
  1. (defstruct estado
  2. ml cl ; misioneros y caníbales en la izquierda
  3. mr cr ; misioneros y caníbales en la derecha
  4. side ; 0 = bote a la izquierda, 1 = derecha
  5. camino) ; lista de pasos
  6.  
  7. (defun estado-valido-p (st)
  8. (let ((ml (estado-ml st))
  9. (cl (estado-cl st))
  10. (mr (estado-mr st))
  11. (cr (estado-cr st)))
  12. (and (>= ml 0) (<= ml 3)
  13. (>= cl 0) (<= cl 3)
  14. (>= mr 0) (<= mr 3)
  15. (>= cr 0) (<= cr 3)
  16. (or (= ml 0) (>= ml cl))
  17. (or (= mr 0) (>= mr cr)))))
  18.  
  19. (defun mover (st m c)
  20. (let* ((ml (estado-ml st))
  21. (cl (estado-cl st))
  22. (mr (estado-mr st))
  23. (cr (estado-cr st))
  24. (side (estado-side st)))
  25. (cond
  26. ((= side 0)
  27. (make-estado :ml (- ml m) :cl (- cl c)
  28. :mr (+ mr m) :cr (+ cr c)
  29. :side 1
  30. :camino (append (estado-camino st)
  31. (list (format nil "~dM~dC ->" m c)))))
  32. (t
  33. (make-estado :ml (+ ml m) :cl (+ cl c)
  34. :mr (- mr m) :cr (- cr c)
  35. :side 0
  36. :camino (append (estado-camino st)
  37. (list (format nil "~dM~dC <-" m c))))))))
  38.  
  39. (defun iguales (a b)
  40. (and (= (estado-ml a) (estado-ml b))
  41. (= (estado-cl a) (estado-cl b))
  42. (= (estado-mr a) (estado-mr b))
  43. (= (estado-cr a) (estado-cr b))
  44. (= (estado-side a) (estado-side b))))
  45.  
  46. (defun repetido-p (nuevo camino)
  47. (some (lambda (e) (iguales e nuevo)) camino))
  48.  
  49. (defparameter *viajes*
  50. '((2 0) (0 2) (1 1) (1 0) (0 1)))
  51.  
  52. (defun resolver (estado final camino)
  53. (when (iguales estado final)
  54. (push estado camino)
  55. (mostrar-solucion (reverse camino))
  56. (return-from resolver))
  57.  
  58. (dolist (v *viajes*)
  59. (let ((m (first v))
  60. (c (second v)))
  61. (when (and (<= (+ m c) 2) (> (+ m c) 0))
  62. (let ((nuevo (mover estado m c)))
  63. (when (and (estado-valido-p nuevo)
  64. (not (repetido-p nuevo camino)))
  65. (resolver nuevo final (cons estado camino))))))))
  66.  
  67. (defun personas (m c)
  68. (concatenate 'string
  69. (make-string m :initial-element #\M)
  70. (make-string c :initial-element #\C)))
  71.  
  72. (defun lado-a-string (m c)
  73. (format nil "[~a]" (personas m c)))
  74.  
  75. (defun mostrar-paso (anterior actual)
  76. (let ((ml (estado-ml anterior))
  77. (cl (estado-cl anterior))
  78. (mr (estado-mr anterior))
  79. (cr (estado-cr anterior))
  80. (side (estado-side anterior))
  81. (ml2 (estado-ml actual))
  82. (cl2 (estado-cl actual))
  83. (mr2 (estado-mr actual))
  84. (cr2 (estado-cr actual))
  85. (side2 (estado-side actual)))
  86.  
  87. ;; Determinar quién cruzó
  88. (let* ((dm (- ml ml2))
  89. (dc (- cl cl2))
  90. (m (abs dm))
  91. (c (abs dc))
  92. (cruce (personas m c)))
  93. (format t "~%Paso ~a (antes de cruzar):~%" (+ 1 (length (estado-camino anterior))))
  94. (if (= side 0)
  95. (format t "~a B ~~~~~~ []~%" (lado-a-string ml cl))
  96. (format t "~a ~~~~~~ B ~a~%" (lado-a-string ml cl) (lado-a-string mr cr)))
  97. (format t "Cruzando con: ~a~%" cruce)
  98. (format t "Paso ~a (después de cruzar):~%" (+ 1 (length (estado-camino anterior))))
  99. (if (= side2 0)
  100. (format t "~a B ~~~~~~ []~%" (lado-a-string ml2 cl2))
  101. (format t "~a ~~~~~~ B ~a~%" (lado-a-string ml2 cl2) (lado-a-string mr2 cr2))))))
  102.  
  103. (defun mostrar-solucion (camino)
  104. (format t "~%====================================~%") ;traviesos
  105. (format t "Solución en ~d pasos~%" (length (estado-camino (car (last camino)))))
  106. (loop for (a b) on camino while b do
  107. (mostrar-paso a b))
  108. (format t "~%====================================~%"))
  109.  
  110. (defun main ()
  111. (let ((inicio (make-estado :ml 3 :cl 3 :mr 0 :cr 0 :side 0 :camino '()))
  112. (fin (make-estado :ml 0 :cl 0 :mr 3 :cr 3 :side 1 :camino '())))
  113. (resolver inicio fin '())))
Success #stdin #stdout 0.02s 30016KB
stdin
Standard input is empty
stdout
Standard output is empty