vecinos en matriz de 2dm representados como lista de lista

Bueno, no puedo entender cómo podría hacerlo en haskell. Por ejemplo, tengo tal matriz.

[[1,2],[3,4]]

y quiero generar una lista de listas con todos los vecinos posibles de cada elemento para esta matriz.

El resultado esperado es:

[[1,2],[1,3],[1,4],[2,1],[2,3],[2,4],[3,1],[3,2],[3,4],[4,1],[4,2],[4,3]]

Sé cómo hacer una función que creará una lista de listas con cables de vecinos de cada celda:

pos how = [ (0+dx,0+dy) | dx <- [0..(how-2)], dy <- [0..how-1] ] :: [(Int,Int)]
neighbour (x,y) how = [ (x+dx,y+dy) | dy <- [-1..1], dx <- [-1..1],
                                      x+dx >= 0, y+dy >= 0, x+dx<=how-2, y+dy <= how-1,
                                      (x,y)/=(x+dx,y+dy) ] :: [(Int,Int)]
all_n how = [ p | x <- pos how, let p = neighbour x how ] :: [[(Int,Int)]]

pero no puedo cambiarlo para que funcione como lo describí.

preguntado el 29 de junio de 12 a las 20:06

Es realmente difícil averiguar lo que estás preguntando en este momento. ¿Puedes ser un poco más claro? Por ejemplo, ¿cómo se define un "vecino"? Por que es [1,4] incluido en su lista de resultados esperados? -

si el celular toca otro incluso con esquina es su vecino -

Entonces por que es [1,4] en su lista de resultados esperados? no es vecino de [1,2] o de [3,4]. -

1 toque 4 con sus esquinas oi48.tinypic.com/20sc20n.jpg no lo ves ? -

Bien, lo tengo ahora. Deberías editar tu pregunta para que quede más clara. -

2 Respuestas

Permítanme esbozar un enfoque muy diferente al que usted sugirió. Cuando hable de vecinos, diré un d-vecino de e es el elemento un paso en la dirección d del elemento e. Así, por ejemplo, en la matriz [[1,2],[3,4]], el número 2 es un vecino derecho del número 1. Tendremos que usar algún código de biblioteca.

import Data.List

Comenzaremos desde lo más simple: busquemos los vecinos derechos de una lista unidimensional.

rightList (x:y:rest) = (x,y) : rightList (y:rest)
rightList _ = []

Podemos encontrar todos los vecinos por la derecha en una matriz eligiendo de manera no determinista una fila de la matriz y encontrando todos los vecinos por la derecha en esa fila.

right m = m >>= rightList

Podemos tomar cualquier función para encontrar vecinos y crear la función para encontrar vecinos en la otra dirección invirtiendo las tuplas. Por ejemplo, los vecinos de la izquierda son iguales a los vecinos de la derecha, pero con los elementos de la tupla intercambiados, por lo que:

swap (x,y) = (y,x)
co direction = map swap . direction
left = co right

¿Qué pasa con los vecinos? En realidad, los vecinos inferiores son solo vecinos derechos en la matriz transpuesta:

down = right . transpose
up   = co down

La siguiente dirección de interés son los vecinos de abajo a la derecha. Este es un poco más complicado; lo que vamos a hacer es recorrer dos listas en paralelo, pero desplazadas por una.

downRight (xs:ys:rest) = zip xs (drop 1 ys) ++ downRight (ys:rest)
downRight _            = []
upLeft = co downRight

Hay una dirección final, a saber, vecinos de arriba a la derecha; estos son vecinos por la derecha si le damos la vuelta a la matriz.

upRight  = downRight . reverse
downLeft = co upRight

Finalmente, para formar todos los vecinos, podemos elegir de manera no determinista una dirección vecina y luego encontrar todos los vecinos en esa dirección.

allDirections = [right, left, up, down,
                 downRight, upLeft, upRight, downLeft]
neighbors m = allDirections >>= ($m)

La salida no está exactamente en el orden que especificó, pero imagino que esto puede no importar mucho.

Respondido el 29 de junio de 12 a las 22:06

Para corregir el código que tiene ahora, proporciono algunas preguntas para las cuales una respuesta reflexiva puede ayudarlo a progresar:

  • how-2 es una cosa extraña Por que es 2 el número correcto para restar?
  • El tipo de all_n es bastante extraño ¿Por qué es una función? (¿Qué representa su argumento?) ¿Por qué devuelve una lista anidada en lugar de una plana?
  • Parece que está rastreando solo un parámetro de tamaño, pero su matriz es una matriz bidimensional. ¿Por qué hay tal discrepancia? (¿Por qué no tiene un parámetro de ancho y alto?)
  • Una vez que tenga una coordenada, ¿sabe cómo obtener el elemento en esa posición de la matriz? (Pista: hay una función (!!) :: [a] -> Int -> [a].) Si tiene una lista de coordenadas, ¿sabe cómo hacer esto para cada elemento de la lista? (Pista: hay una función map :: (a -> b) -> ([a] -> [b]).)

¡Buena suerte!

Respondido el 29 de junio de 12 a las 22:06

-1 porque!! comienza desde 0 y sigue -1 porque su matriz n/n-1 - whd

@whd Estoy seguro de que conoce el problema mejor que yo, pero [[1,2],[3,4]] seguro que no vea como una matriz nx(n-1). - Daniel Wagner

lo sé, pero era la forma más fácil de mostrar lo que quiero decir y sus funciones también funcionarán con otra matriz: whd

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.