Problema de las jarras
En el problema de las jarras (A,B,C) se tienen dos jarras sin marcas de medición, una de A litros de capacidad y otra de B. También se dispone de una bomba que permite llenar las jarras de agua.
El problema de las jarras (A,B,C) consiste en determinar cómo se puede lograr tener exactamente C litros de agua en la jarra de A litros de capacidad.
Definir, mediante búsqueda en espacio de estados, la función
1 |
jarras :: (Int,Int,Int) -> [[(Int,Int)]] |
tal (jarras (a,b,c)) es la lista de las soluciones del problema de las
jarras (a,b,c). Por ejemplo,
1 2 3 |
λ> take 2 (map snd (sort [(length xs,xs) | xs <- jarras (4,3,2)])) [[(0,0),(0,3),(3,0),(3,3),(4,2),(0,2),(2,0)], [(0,0),(4,0),(1,3),(1,0),(0,1),(4,1),(2,3)]] |
La interpretación [(0,0),(4,0),(1,3),(1,0),(0,1),(4,1),(2,3)] es:
- (0,0) se inicia con las dos jarras vacías,
- (4,0) se llena la jarra de 4 con el grifo,
- (1,3) se llena la de 3 con la de 4,
- (1,0) se vacía la de 3,
- (0,1) se pasa el contenido de la primera a la segunda,
- (4,1) se llena la primera con el grifo,
- (2,3) se llena la segunda con la primera.
Otros ejemplos
1 2 3 4 |
λ> (snd . head . sort) [(length xs,xs) | xs <- jarras (15,10,5)] [(0,0),(15,0),(5,10)] λ> jarras (15,10,4) [] |
Nota: Las librerías necesarias se encuentran en la página de códigos.
Soluciones
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
import I1M.BusquedaEnEspaciosDeEstados -- Un problema queda determinado por las capacidades de las dos jarras y -- el contenido que se desea lograr -- Un estado es una lista de dos números. El primero es el contenido de -- la jarra de 4 litros y el segundo el de la de 3 litros. type EstadoJarras = (Int,Int) inicialJarras :: EstadoJarras inicialJarras = (0,0) esFinalJarras :: (Int,Int,Int) -> EstadoJarras -> Bool esFinalJarras (_,_,c) (x,_) = x == c sucesoresEjarras :: (Int,Int,Int) -> EstadoJarras -> [EstadoJarras] sucesoresEjarras (a,b,_) (x,y) = [(a,y) | x < a] ++ [(x,b) | y < b] ++ [(0,y) | x > 0] ++ [(x,0) | y > 0] ++ [(a,y-(a-x)) | x < a, y > 0, x + y > a] ++ [(x-(b-y),b) | x > 0, y < b, x + y > b] ++ [(x+y,0) | y > 0, x + y <= a] ++ [(0,x+y) | x > 0, x + y <= b] -- Los nodos son las soluciones parciales type NodoJarras = [EstadoJarras] inicialNjarras :: NodoJarras inicialNjarras = [inicialJarras] esFinalNjarras :: (Int,Int,Int) -> NodoJarras -> Bool esFinalNjarras p (e:_) = esFinalJarras p e sucesoresNjarras :: (Int,Int,Int) -> NodoJarras -> [NodoJarras] sucesoresNjarras p n@(e:es) = [e':n | e' <- sucesoresEjarras p e, e' `notElem` n] solucionesJarras :: (Int,Int,Int) -> [NodoJarras] solucionesJarras p = buscaEE (sucesoresNjarras p) (esFinalNjarras p) inicialNjarras jarras :: (Int,Int,Int) -> [[(Int,Int)]] jarras p = map reverse (solucionesJarras p) |
No he sido capaz de que aparezcan las soluciones en el orden mostrado en los ejemplos.
Con una distinción bastante amplia de casos para optimizar lo máximo posible
En la línea 12 debería ir ‘d < a' y no 'd < 4'. En la 14 debería ir 'e < b' y no 'e < 3'.